Pixel shading not so smooth

369 Views Asked by At

I am implementing a basic heightmap with simple shading (ambient + diffuse). The shading is implemented on the fragment shader, which is shown below.

#version 330

in  vec3 fragNormal;
out vec4 outColor;

uniform vec3 lightDirection;
uniform vec3 lightColor;
uniform vec3 objectColor;

void main()
{
    float ambientStrength = 0.1f;
    vec3 ambientColor = ambientStrength * lightColor;

    vec3 norm = normalize(fragNormal);
    float diff = max(dot(norm, -normalize(lightDirection)), 0.0f);
    vec3 diffuseColor = diff * lightColor;

    outColor = vec4((ambientColor + diffuseColor) * objectColor, 1);
}

What I do is to calculate a simple diffuse component based on the normal fragNormal. This variable is passed directly from the vertex shader.

Here is a screenshot of what I currently have:

enter image description here

Is this the expected result from a heightmap with pixel shading? I am a little bit annoyed by the fact that the surface is not really smooth.

But if that is expected, is the any technique that improves what I currently have?

To calculate the normals, I used the following algorithm: Finite difference method (Stack Overflow)

1

There are 1 best solutions below

1
On

Using a pixel shader does not give you smooth shading for free. In general, having only a normal per triangle gives you the flat shading you see in your screenshot. What you want is some method of calculating a weighted average of normals for each vertex - the method of weighting is really up to you (here is a list of possibilities).

And here is an SO post giving pseudo-code for finding the weighted vertex normals.

The method you posted seems to be a fast way of approximating normals for a point on a heightmap. This page seems to indicate doing something similar (calculating the sum of normals around a point) to achieve a similar smoothing effect while still using finite difference.