Sign in to follow this  
sipickles

World space normal maps

Recommended Posts

I am having trouble using a normal map to light my terrain. My terrain doesnt have normal, binormal and tangent data. Its a dynamic geoclipmapped surface and I dont want to spare the processing to do this on the fly. For this reason I want to use a normal map to light it. I am planning on using a WORLD SPACE normal map, since the terrain is static, and I wont need all the binormal/tangent calculations. Can I use a texture shader to generate the normal map at runtime, from the heightmap? And do I calculate the normal, then convert it to: D3DCOLOR( normal.x, normal.y, normal.z, 1.0f); ? Thanks Simon

Share this post


Link to post
Share on other sites
Hello,


I'm doing something similar to what you want to do with my water rendering... http://rbangs.blogspot.com

I store the normal data with my heightmap data, this is all generated on a seperate render pass by combining heightmaps that move using additive blending (the blend modes are setup so that anything written to the render target is ADDED to it).

My heightmap consists of 4 channels (RGBA), in R I store the displacement, and the other three channels store the displacement for pixels around it (G = bottom left, B = top, A = bottom right). This is done for three reasons, it can be generated really easy, just using additive blending. It can be used to do a bilinear lookup using a single vertex shader texture lookup (as mentioned in GPU Gems 2). And lastly I can use it to calculate the normal with a single lookup, as we now have 4 points which lie on the plane.

If I've confused you at all the code might help explain things a little better.


// Get our values off our textures.
float4 fHeightmap = tex2D( HeightmapSampler, In.Texture ); // Combined Heightmap (1024x1024)

const float fSpacing = 0.07f; // Spacing on our triangle for calculating our normal.

// Triangle points for calculating our normal.
float3 G = float3( -fSpacing, fHeightmap.g, -fSpacing ); // Bottom Left Corner
float3 B = float3( 0.0f, fHeightmap.b, fSpacing ); // Top Middle
float3 A = float3( fSpacing, fHeightmap.a, -fSpacing ); // Bottom Right.

// Calculate the vectors between these points.
float3 V_gb = B - G;
float3 V_ab = B - A;

// And finally calculate our normal for our current pixel.
float3 Normal = cross( V_gb, V_ab );





Richard.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this