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:
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)
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.