I am drawing my terrain by rendering a static quad mesh several times and then displacing vertices using a heightmap. As such I need to generate normals. I am primarily interested in quality over speed.

What is the best way to do this? Precompute a normal-map and sample it in the pixel shader? Or generate them in the vertex shader somehow?

  • \$\begingroup\$ This would be an ordinary partial difference of adjacent texels of the height map, no? \$\endgroup\$
    – DMGregory
    Commented Dec 18, 2021 at 13:00
  • \$\begingroup\$ in the Question, you say you want to "precompute", in the comment of the answer of ErnieDingo you say you want to generate them in a shader. So what is it? \$\endgroup\$
    – Raildex
    Commented Apr 5 at 7:58

1 Answer 1


Note: These are my experiences so everyone finds their own path!

I use heightmaps in game, but after applying it to the mesh I then add the normal to the vertex as another attribute. I can use this with other attributes so I can ignore areas or apply a bias to a normal, or where I do want to normalise. I pass the normal into the vertex shader along with the rest of the vertex data, the normal will be linear interpolated so I will get normal that accurately is reflected in the pixel shader (just needs to be normalised as lerping denormalises).

This is a far more accurate representation than a normal map, unless you have a high res version of that map than you wont get near the accuracy.

The other piece that I would steer clear of normal maps for terrain. If you ever want to rotate your world, then you need in your pixel shader to sample a point, apply the matrix transform to it then its in world space. If you use normals through the vertex shader, you can apply the same matrix transform once per vertex, not per pixel. Pressure on the pixel shader is the thing I try to avoid. It also means one less bilinear sample in the pixel shader. The transform of the sampling to world space is similar to what you do for calculating normal maps on a model.

sample of normals per vertex

  • \$\begingroup\$ My mesh is just a flat quad that gets displaced with the terrain heightmap; I have no normals to interpolate. Thus I need to generate them in the shaders \$\endgroup\$ Commented Mar 26, 2020 at 21:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .