Normal Maps

Started by
8 comments, last by kapru 20 years, 3 months ago
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
Advertisement
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.
Ok so ive created the normal map how do i apply is to the landscape.
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
Im trying to use the normal map to shade the landscape once ive created it how do i render it
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.
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
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

What other good methods are there for quick terrain lighting
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

This topic is closed to new replies.

Advertisement