# Calculating vertex normals on the GPU

I have some height-map sampled on a regular grid stored in an array. Now, I want to use the normals on the sampled vertices for some smoothing algorithm. The way I'm currently doing it is as follows:

1. For each vertex, generate triangles to all it's neighbours. This results in eight neighbours when using the 1-neighbourhood for all vertices except at the borders.

 +---+---+
¦ \ ¦ / ¦
+---o---+
¦ / ¦ \ ¦
+---+---+

2. For each adjacent triangle, calculate it's normal by taking the cross product between the two distances.

3. As the triangles all have the same size when projected on the xy-plane, I simply average over all eight normals then and store it for this vertex.

However, as my data grows larger, this approach takes too much time and I would prefer doing it on the GPU in a shader code. Is there an easy method, maybe if I could store my height-map as a texture?

• You want to smooth the normals of an already generated terrain, or you want to create the terrain from a height map? – Jonathan Connell Jun 22 '11 at 10:26
• I want to get the normals for all my vertices, the heightmap is already there. – Etan Jun 22 '11 at 12:04
• I don't quite understand the issue - where's the problem with taking the vertex that the vertex shaders gives you and calculating the normal in a straight forward manner? You could just apply that specific shader to whatever piece of geometry that you need it for. If you need the heightmap in the vertex shader, there are methods for texture fetching depending on what language you use (google should help you). – TravisG Jun 22 '11 at 12:21
• Maybe you can simply use 4-connected pixels. This might result in similar results with half the performance hit. But if your heightmap is static your should consider a different approach: If it is static at compilation time: implement a pipeline extension, if it is static at runtime, use a onetime terrain generation algorithm. Vertex-displacement is only useful, when your heightmap changes during runtime, otherwise it is waste of GPU performance. – 0xBADF00D Sep 19 '13 at 6:39

• The map is static, and is like 2000x2000 big. I want to tune the parameters of the smoothing algorithm with it and the normals of the 8 neighbours is just required for this. I'm wondering if it is possible to do such normal calculations on the gpu in the vertex shader, and heishe's comment gave me quite a hint. Texture fetch in the vertex shader seems to be the best solution to do my normal calculation. – Etan Jun 22 '11 at 16:05