Wednesday, January 4, 2017

directx - 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.


With normal averaging


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


Wihtout normal averaging



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)


Heightmap grid


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.



Answer



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


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...