# Problem calculating normals for heightmaps

So far I have been using normal avering to calculate the normals for my vertices in my heightmap, with good graphical result (see picture), however it is terribly slow. With a incresing image size the calculation time increases exponationally.

So I wanted to try implementing this algorithm insteed, but it isn't going very well. I have tried to trow around the variables a bit and tried diffrent combinations but nothing seems to work. Something that seems to be recurring is this shadow line pattern i get everywhere (the picture is a bit dark but i hope you can see the pattern).

My best guess to why this isnt working is because the algorithm isnt taking 2 of the neighboring vertices in to account in the calculation (See picture, blue is vertice we are trying to calculate normal for, green is the ones used in algorithm, red isnt used)

However, this algorithm seem to pop up in alot of places so that makes me think it has to be rigth. So im not sure if im doing it wrong somehow or if the algorithm is wrong. I was hoping some of you guys had runed in to the same problem and could give me some tips to what might cause this problem.

This is my translation of the algorithm im using

int cols = hmInfo.terrainWidth;
int rows = hmInfo.terrainHeight;

#define height(x, y)  hmInfo.heightMap[(y*cols) + x].y
XMVECTOR normal;
for(DWORD y = 0; y < rows; ++y)
{
for(DWORD x = 0; x < cols; ++x)
{

float sx =  height( x < cols-1 ? x+1 : x, y) - height(x ? x-1 : x, y);
if (x == 0 || x == cols-1)
sx *= 2;

float sy =height( x , y < rows-1 ? y+1 : y)- height(x, y ?  y-1 : y);
if (y == 0 || y == rows -1)
sy *= 2;

normal=  XMVectorSet(-sx , 2.0f,  sy , 0.0f);
normal = XMVector3Normalize(normal);

tempSubset.vertices[y*cols+x].normal = XMFLOAT3(XMVectorGetX(normal),XMVectorGetY(normal), XMVectorGetZ(normal));

}
}


PS. Seeing how it works with normal averaging im fairly sure that all other parts of the program is working fine DS.

• Note that the algorithm grows linearly in the number of cells or quadratically in the side (for squareish terrains), not exponentially. – Lars Viklund Feb 17 '14 at 1:38
• i dont think that was the case for the normal averagin algorithm i used, because for each vertex your had to check all the faces if they used that one. A 100 x 100 pixel bmp took 1 min, a 200 x 200 took 30 mins :P But i was probebly using a bad algorithm, hence why im swapping :) – Fredrik Boston Westman Feb 17 '14 at 10:48

turns out you have to be careful with your macros

#define height(x, y)  hmInfo.heightMap[(y*cols) + x].y


The y on the end was replaced by the macro

Working version

#define height(a, b)  hmInfo.heightMap[(b*cols) + a].y


Im supprised how this compiled and even worked without breaking