I know I've been spamming a bit the forums, but please bare with me.

I have this old DX9 CPU based terrain LOD system and I'm updating it to a modern DX11 GPU based one. Progress has been slow but very fun, since I get to replace hundreds of lines of code doing expensive CPU LOD operations with a few GPU lines and I also get a performance boost out of it.

I am not going to talk a bout terrain height across LOD and morphing because these questions have fairly solid answers in my head.

It is about lighting. Even with physically based rendering, the good old cosine factor, the nDotL plays a huge role since we multiply by it. So I want to get it right, but I am getting some weird results as I move across LOD/MIP levels in my normal map generated based on the height map.

Supposing that we have a sampling rate of 1, meaning for NxN vertices we have NxN texels in our height map and a direction of float3(0.80, -0.40, 0.0), I have a first question.

1. Is the following output of nDotL correct, useful for physically based rendering and must be used as a general guideline across all LOD levels, meaning that whatever the sampling rate, your nDotL should roughly follow this curve?

**ndotl1.png** **390.66KB**
0 downloads

This looks correct for a low resolution (128x128) input texture.

But if I double the height map and normal map resolution, but adjust the sample rate (half it) so that the amount of vertices remains the same, I get this result, which changes the the nDotL curve:

**ndotl2.png** **573.59KB**
0 downloads

This because I am creating the normal map based on sampling of 4 points in the height map:

float4 GenNM(VertexShaderOutput input) : SV_TARGET { float ps = 1 / size; //ps *= size / 128; float3 n; n.x = permTexture2d.SampleLevel(permSampler2d, float4(input.texCoord.x - ps, input.texCoord.y, 0, 0), 0).x * 30 - permTexture2d.SampleLevel(permSampler2d, float4(input.texCoord.x + ps, input.texCoord.y, 0, 0), 0).x * 30; n.z = -(permTexture2d.SampleLevel(permSampler2d, float4(input.texCoord.x, input.texCoord.y - ps, 0, 0), 0).x * 30 - permTexture2d.SampleLevel(permSampler2d, float4(input.texCoord.x, input.texCoord.y + ps, 0, 0), 0).x * 30); n.y = 2; n = normalize(n); n = n * 0.5 + 0.5; return float4(n, 1); }

permTexture2d is the wrongly named heightMapTexture and 30 is the world scale. When I double the height map resolution, it becomes finer and the height points closer, so some of the overall curve of the lower resolution height map is lost, rather than adding detail to it. Am I understanding this right?

Doubling the height and normal resolution again and halving the sample rate so that we have the same amount of vertices I get this result:

**ndotl3.png** **590.87KB**
0 downloads

By the time I get to the desired resolution, the normals become quite flat and so does the lighting.

The reason for generating a high resolution map is that this is the input for LOD 0 close to the camera terrain. LOD 0 is rendered using a lot of vertices. As I move away from the camera, I start using less vertices, spaced further apart. The final LOD will have the 128x128 vertices, like in the first low resolution screenshot.

So the next question is:

2. How should the normal map on full resolution look? More like the one in the first screenshot, but with more detail, or more like in the last screenshot, flat.

3. How consistent should be the various MIP levels of the normal map as I go down in resolution?