Archived

This topic is now archived and is closed to further replies.

kapru

Normal Maps

Recommended Posts

Ive finally perfected my terrain engine been a long time coming ive just added vertex shading by manually calculating all ther normals. but im wondering how normal maps are created and used

Share this post


Link to post
Share on other sites
There is a D3DX function which creates a normal map from a height map.
You can also load the vertex buffer and index buffer into a mesh and then call a function to create the normals, which will calculate averaged normals.

Share this post


Link to post
Share on other sites
a normal map is a texture where you store normals as rgb data
a normal is x,y,z where x*x+y*y+z*z=1
to set a pixel of the normal map you do
r = Round(255*(0.5*x+0.5));
g = Round(255*(0.5*y+0.5));
b = Round(255*(0.5*z+0.5));

when you use the texture, if you bias it by a half and scale it by two, you obtain the normal again. (scale_bias)

In the case of the terrain, you could say that the normals encoded in the map are relative to the position matrix of the terrain, which is ID if the terrain coordinates are absolute.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well, first of all, you''ll have to use pixel shaders. If you''ve used pixel shaders before you can go on, or you''ll have to start with something more simple. ATI web site have some nice examples of bump mapping for your reference.

Share this post


Link to post
Share on other sites
Im not really after bump mapping im wanting to use normal maps to shade my terrain so i dont have to spend time calculating every vertex''s normal is the landscape changes

here what im doing so far

here i create the normal map based on the terrain height map

CFrameWorkApplication::ComputeTerrainNormalMap()
{
//terrNormalMap;

LPDIRECT3DTEXTURE8 temptexture;
D3DLOCKED_RECT lr;
unsigned int *bits;
unsigned int pitch;
int i,j;
D3DSURFACE_DESC desc;
char col;

//lock the temp texture then copy the heightmap data to the

//red component of the texture

D3DXCreateTexture(d3ddevice,terrSizeX,terrSizeY,1,D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&temptexture);
D3DXCreateTexture(d3ddevice,terrSizeX,terrSizeY,1,D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&terrNormalMap);

temptexture->GetLevelDesc(0, &desc);
temptexture->LockRect( 0, &lr, 0, 0 );
bits=(unsigned int*)lr.pBits;
pitch=lr.Pitch/4;

//Copy the data onto the texture

for(i=0;i<(signed)desc.Width;i++)
for(j=0;j<(signed)desc.Height;j++)
{
col=HeightMap[j*terrSizeX+i];
((DWORD*)lr.pBits)[desc.Width*j+i] = D3DCOLOR_ARGB(0,col,0,0);
}
temptexture->UnlockRect(0);

//now create the normal map

D3DXComputeNormalMap(terrNormalMap,temptexture,NULL,D3DX_NORMALMAP_MIRROR,D3DX_CHANNEL_RED,terrHeightScale);
//release the temp texture

temptexture->Release();
}


now i want to use this newly created texture as a second texture stage when i draw my terrain to shade the terrain. like you would if you were using vertex normals.

the reason im trying to do it this way is because calculating the vertex normals takes too much time if it needs to be done run time

thanks for any help

Share this post


Link to post
Share on other sites
Unless you have very small normalmap, it takes more time to calculate that instead of vertex normals.
Take into account the total amount of processing for each option

-Nik

Share this post


Link to post
Share on other sites
You should really establish normals for any kind of lighting. Whether they are vertex- or pixel-based, that''s up to you to determine.

Weigh the benefits of each method, then determine what to do.
In the end, diffuse lighting is just a simple equation of dot3(normal,lightDir) * attenuationFactor; nothing magical

-Nik

Share this post


Link to post
Share on other sites