Weird Artifacts in normals of displacement shader
Asked Answered
M

4

0

Hello everyone.
I wrote a simple shader to displace the vertices of a plane using a noise image texture.
The plane displaces correctly but the problem occurs when I calculate the normals. There are some artifacts that occur in the result.


This is how it looks without lighting to show the artifacts properly.

Here's the shader used:

` shader_type spatial;

uniform sampler2D displacement_texture;
uniform float height_scale = 1.0;
uniform float uv_offset = 0.01;

void vertex() {
    float left = texture(displacement_texture, UV + vec2(-uv_offset, 0)).r;
    float right = texture(displacement_texture, UV + vec2(uv_offset, 0)).r;
    float bottom = texture(displacement_texture, UV + vec2(0, -uv_offset)).r;
    float top = texture(displacement_texture, UV + vec2(0, uv_offset)).r;

    vec3 va = vec3(-uv_offset, (left - right) * height_scale, 0);
    vec3 vb = vec3(0, (bottom - top) * height_scale, uv_offset);

    NORMAL = normalize(cross(vb, va)); // Reversed cross product

    vec4 tex_color = texture(displacement_texture, UV);
    VERTEX.y += tex_color.r * height_scale;
}

void fragment() {
    ALBEDO = vec3(1.0);
}

`

I don't know why the artifacts form. I'm using Godot 3.5.3 stable

Maley answered 19/2 at 18:54 Comment(0)
M
0

You can't recalculate normals in the vertex shader. Use a displacement texture in combination with a normal texture.

VERTEX.y = texture(Displacement, UV).x * dispAmount;

in fragment:
NORMAL_MAP = texture(normal_tex, UV).rgb;

Modality answered 19/2 at 21:3 Comment(0)
S
0

Provide a Minimum Reproductive Project. Also useful tip, render your normal RGB value as albedo so you can see just how wrong it is.

Spectrohelioscope answered 19/2 at 19:44 Comment(0)
M
0

Spectrohelioscope
here is the MRP

min-disp-woes.zip
9kB

And here is the normal as albedo

Maley answered 19/2 at 20:24 Comment(0)
M
0

You can't recalculate normals in the vertex shader. Use a displacement texture in combination with a normal texture.

VERTEX.y = texture(Displacement, UV).x * dispAmount;

in fragment:
NORMAL_MAP = texture(normal_tex, UV).rgb;

Modality answered 19/2 at 21:3 Comment(0)
M
0

Modality
Thank you. This worked like a charm

Maley answered 19/2 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.