hi,
how do i convert a heightmap to a normal map? I found two different solutions but i need a correct explanation
(i)
dx=heightmap[i][j]-heightmap[i-1][j]
dy=heightmap[i][j]-heightmap[i][j+1]
vector3d normal=(dx,dy,1)
normal.normalize()
(ii) dz1=heightmap[i][j]-heightmap[i-1][j]
dz2=heightmap[i][j]-heightmap[i][j+1]
dx=(1,0,dz1)
dy=(0,1,dz2)
normal=dx.cross(dy)
the above two procedures don't seem to be the same to me. the first one samples the heights in the X and Y directions whereas the second one defines the X and Y components as unit. which one is the correct?
heightmap to normal map conversion question
Started by magneeto, Jan 09 2007 06:13 AM
3 replies to this topic
#1
Posted 09 January 2007 - 06:13 AM
#2
Posted 09 January 2007 - 06:51 AM
The second one is correct, but the first one is almost correct. The cross product of (1, 0, dz1) and (0, 1, dz2) is (0*dz2 - dz1*1, dz1*0 - dz2*1, 1*1 - 0*0) = (-dz1, -dz2, 1), which is the same as the first one except for the signs being flipped in the x and y coordinates. What the second one is doing is really defining two tangent vectors dx and dy, and the normal is of course the cross product of the tangents.
reedbeta.com - developer blog, OpenGL demos, and other projects
#3
Posted 09 January 2007 - 10:25 AM
The first one is a forward difference setup. It is used in DUDV bump mapping.
#4
Posted 09 January 2007 - 03:06 PM
I always found the generated normalmaps looked too blocky using that technique, so I switched to a Sobel filter:
vector3d normal; // Get sobel samples float dx, dy, sobelTaps[8]; sobelTaps[0] = heightmap[i - 1][j - 1]; sobelTaps[1] = heightmap[i ][j - 1]; sobelTaps[2] = heightmap[i + 1][j - 1]; sobelTaps[3] = heightmap[i - 1][j + 1]; sobelTaps[4] = heightmap[i ][j + 1]; sobelTaps[5] = heightmap[i + 1][j + 1]; sobelTaps[6] = heightmap[i - 1][j ]; sobelTaps[7] = heightmap[i + 1][j ]; // Do y sobel filter dy = sobelTaps[0] * +1.0f; dy += sobelTaps[1] * +2.0f; dy += sobelTaps[2] * +1.0f; dy += sobelTaps[3] * -1.0f; dy += sobelTaps[4] * -2.0f; dy += sobelTaps[5] * -1.0f; // Do x sobel filter dx = sobelTaps[0] * -1.0f; dx += sobelTaps[6] * -2.0f; dx += sobelTaps[3] * -1.0f; dx += sobelTaps[2] * +1.0f; dx += sobelTaps[7] * +2.0f; dx += sobelTaps[5] * +1.0f; // Cross Product of components of gradient reduces to: normal.x = -dx; normal.y = -dy; normal.z = 1;
"Stupid bug! You go squish now!!" - Homer Simpson
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











