Bumpmap normals
When I convert a say 256x256 grayscale bumpmap into normals i take the difference in height(grayscale) between pixel u,u+1 and v,v+1.
This works but is will actually result in the normal at (u+0.5,v+0.5). I could just as well have sampled u-1,u and v-1,v and gotten the sample of (u-0.5,v-0.5). Is there a way to take all the slopes around u,v into account instead of arbitrarily measurement to "the left or to the right".
What I want is some pseudocode for sampling heights around u,v to get a normal that is affected by its surrounding pictures on ALL sides.
Depends if you're doing that on the fly (rendering time) or not.
On the fly: you can take the partial derivative around the, say bilinearly filtered, u and v +/-1. That works ok, but it's far from perfect like you've noticed.
If you can preprocess that into a proper normal map, then you have more options; ie a Sobel or Prewitt filtering does wonder sometimes, but it depends on the input.
Check nVidia's photoshop normal map filter plugin to get an idea of what makes sense.
On the fly: you can take the partial derivative around the, say bilinearly filtered, u and v +/-1. That works ok, but it's far from perfect like you've noticed.
If you can preprocess that into a proper normal map, then you have more options; ie a Sobel or Prewitt filtering does wonder sometimes, but it depends on the input.
Check nVidia's photoshop normal map filter plugin to get an idea of what makes sense.
You could take the difference between pixels u+1 and u-1 (resp. v+1 and v-1).
This is called "centered difference" and is actually the sum of right difference and left difference:
(h(u+1,v)-h(u,v)) + (h(u,v)-h(u-1,v)) = h(u+1,v)-h(u-1,v)
(same for v-differences).
This is called "centered difference" and is actually the sum of right difference and left difference:
(h(u+1,v)-h(u,v)) + (h(u,v)-h(u-1,v)) = h(u+1,v)-h(u-1,v)
(same for v-differences).
Height maps can be looked upon as function of Y with the independent variables being X and Z (i am assuming OpenGL, Right Hand Coordinate System ).
Now mathematically the surface normal can be found out by:
N = - dy/dx i + j - dy/dz k
and ofcourse, dont forget to normalize N later on.
Now, how do u calculate those dy/dx and dy/dz terms are all ur choice, u can simple do this
to find dy/dx at a point (X,Z)
dy/dx[X,Z] = (height(X+1,Z) - height(X,Z)) / 1
or maybe to take a sort of average we can do this
dy/dx[X,Z] = (height(X+1,Z) - height(X-1,Z)) / 2
Similary we can find out
dy/dz[X,Z] = (height(X,Z+1) - height(X,Z-1)) / 2
now simply plugin this values into the first equation.. (there will be some errors though, but we can always live with these errors )
Normalize N and then convert them to color space values
R = (Nx + 1) / 2;
G = (Nz + 1) / 2;
B = (Ny + 1) / 2;
Notice that in the above calculation we have mapped Nz to G (Green) channel.. well thats purely because of the custom that normal maps have up-vectors to be the Blue channel. But you can always change that custom for your own application. But this way, making B the up vector, u make ur normal map PORTABLE :P
Now mathematically the surface normal can be found out by:
N = - dy/dx i + j - dy/dz k
and ofcourse, dont forget to normalize N later on.
Now, how do u calculate those dy/dx and dy/dz terms are all ur choice, u can simple do this
to find dy/dx at a point (X,Z)
dy/dx[X,Z] = (height(X+1,Z) - height(X,Z)) / 1
or maybe to take a sort of average we can do this
dy/dx[X,Z] = (height(X+1,Z) - height(X-1,Z)) / 2
Similary we can find out
dy/dz[X,Z] = (height(X,Z+1) - height(X,Z-1)) / 2
now simply plugin this values into the first equation.. (there will be some errors though, but we can always live with these errors )
Normalize N and then convert them to color space values
R = (Nx + 1) / 2;
G = (Nz + 1) / 2;
B = (Ny + 1) / 2;
Notice that in the above calculation we have mapped Nz to G (Green) channel.. well thats purely because of the custom that normal maps have up-vectors to be the Blue channel. But you can always change that custom for your own application. But this way, making B the up vector, u make ur normal map PORTABLE :P
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement