# Bumpmap normals

This topic is 5055 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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.

##### Share on other sites
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.

##### Share on other sites
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).

##### Share on other sites
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

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 15
• 14
• 46
• ### Forum Statistics

• Total Topics
634057
• Total Posts
3015286
×