Skip to main content
gamedev.net
🔒 Locked

Normal Maps

Started by kapru Jan 7, 2004 at 9:21 AM 8 replies 900+ views
Original Post
kapru
kapru
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
Fidelio66
Fidelio66
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.
kapru
kapru
Ok so ive created the normal map how do i apply is to the landscape.
janos
janos
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.
Act of War - EugenSystems/Atari
kapru
kapru
Im trying to use the normal map to shade the landscape once ive created it how do i render it
kapru
kapru
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
Nik02
Nik02
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
Niko Suni
kapru
kapru
What other good methods are there for quick terrain lighting
Nik02
Nik02
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
Niko Suni

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.