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

  • 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;

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

    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;