Jump to content
  • Advertisement

Archived

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

Wavewash

My attempt at Shadow Mapping on Old Hardware (Results)

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

//I am posting this in hopes that it may help someone else. So I have been trying to tackle shadow mapping on old hardware. Now shadow mapping by itself is fairly easy. Render the object without textures and lighting with the material color of the shadow and render it to a texture. Then project the texture behind the object onto the shadow recievers. This technique is explained in far more detail by cbloom (http://www.cbloom.com/3d/techdocs/shadowmap.txt). This works for old hardware but what I wanted was self shadowing shadow maps. So what's the problem? Problem: Old hardware (Voodoo3/TNT2) does not allow for lockable depth buffers that can be used to do depth comparisons from the light's view to the camera view. Work Around: Older hardware allows for render to textures. The surfaces are lockable. So my goal was to somehow get some depth information onto a lockable surface to use for comparison. Pixel shaders were not programmable on the older hardware, they were set with certain abilities and that's all you had to work with. One of which was per pixel fog. Fog is depth dependent. By setting fog to entirely white and clearing a backbuffer surface to all black you can render your geometry to that surface and gain depth information. Here are the depth buffer pictures I produced using this technique: View from the light: View from the Camera: Now issues arising from having per pixel fog depth maps is that you are only getting a 8 bit depth buffer. This doesn't allow for very much accuracy at all. The only way I could think of getting a higher bit depth buffer was to render the scene using the same method except rendering it in red blue and green by changing the fog color. So the process would look as follows: //for a scene with a far clipping plane of 300 clear backbuffer and depth buffer Change fog color to Red Render scene from 0 to 100 Change fog color to Green Render scene from 100 to 200 Change fog color to Blue Render scene from 100 to 300 and then if you like you can create an array and fill it with the compiled values from the backbuffer. Issues with this is you're rendering 3 times to get only 24 bit accuracy. Since RGB are all 8 bit values. The point of this excersize was to create soft shadows on old hardware but as soon as I began to do filtering on the shadow maps (depth buffers) the performance degraded even further to the point where a scene with 2500 triangles was rendering at 13 frames per second on my test machine (800mhz + voodoo5500). My more powerful machine (2700xp + Radeon9700) was able to handle this without any issues but then again this is all unnecessary on such a machine because you can render a depth stencil to texture on such a card. So all work on soft shadows on old hardware ended there. Conclusion: It is possible but it's too slow. Here is the following code dump stripped out of my engine so I appologize for the messyness. This code does no more then render the scene from the lights veiw to a texture and render the camera view to a texture using the fog depth method.
LPDIRECT3DTEXTURE8  shadowRegtex;
LPDIRECT3DSURFACE8  shadowRegtexpointer;
LPDIRECT3DTEXTURE8  shadowtex;
LPDIRECT3DSURFACE8  shadowtexpointer;

LPDIRECT3DSURFACE8	shadowtexS;
LPDIRECT3DSURFACE8	shadowdepthS;

LPDIRECT3DSURFACE8 backbuffer;
LPDIRECT3DSURFACE8 zbuffer;

//get current info

	g_pd3dDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&backbuffer);
	g_pd3dDevice->GetDepthStencilSurface(&zbuffer);
	
	//create texture

	g_pd3dDevice->CreateRenderTarget(256, 256, d3ddm.Format, 
							D3DMULTISAMPLE_NONE, FALSE,
							&shadowtexS);

	g_pd3dDevice->CreateDepthStencilSurface(256, 256,
						    D3DFMT_D24S8, D3DMULTISAMPLE_NONE,
							&shadowdepthS);

	D3DXCreateTexture(g_pd3dDevice,256,256,1,
							D3DUSAGE_RENDERTARGET,d3ddm.Format,
							D3DPOOL_DEFAULT,&shadowtex);

	shadowtex->GetSurfaceLevel(0,&shadowtexpointer);

	D3DXCreateTexture(g_pd3dDevice,256,256,1,
							D3DUSAGE_RENDERTARGET,d3ddm.Format,
							D3DPOOL_DEFAULT,&shadowRegtex);

	shadowRegtex->GetSurfaceLevel(0,&shadowRegtexpointer);
	


	D3DXMatrixLookAtLH(&lightview,	&D3DXVECTOR3( -100.0f, 100.0f,0.0f ),
									&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
									&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
//////////rendering code//////////

g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	g_pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, TRUE);

	g_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,  0xff000000);
	g_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, TRUE);
	//g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );


	//unnecessary because you can just transform the normal view

	g_pd3dDevice->SetRenderTarget(shadowRegtexpointer,shadowdepthS);
	g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);

	//Render Objects

	Levelman.lightrender();
	BGOman.lightrender();
	GMouse.Render();

	D3DXSaveTextureToFile("camera.bmp",D3DXIFF_BMP, shadowRegtex, NULL);


	g_pd3dDevice->SetTransform(D3DTS_VIEW, &lightview);
	g_pd3dDevice->SetRenderTarget(shadowtexpointer,shadowdepthS);//shadowdepthS);

	g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);

	//Render Objects

	Levelman.lightrender();
	BGOman.lightrender();
	GMouse.Render();

	D3DXSaveTextureToFile("light.bmp",D3DXIFF_BMP, shadowtex, NULL);

        g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	g_pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, TRUE);
	g_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE);
	//////////////////////////////////////

	//Get Back to Normal Rendering (From Shadow Mapping)

	g_pd3dDevice->SetRenderTarget(backbuffer,zbuffer);

My engine is moving to shadow volumes now. ~Wave [edited by - Wavewash on February 10, 2004 3:34:45 AM]

Share this post


Link to post
Share on other sites
Advertisement
That is an interesting work-around on some very old hardware. Nice job.

Personally, I''m designing my engine around programmable shaders, because if it ever gets done, the standard cards will most likely be at that level of support. Hopefully

Share this post


Link to post
Share on other sites
I decided early on that I wanted to have my target machine be an 800mhz with a Geforce2/Voodoo5500 card in it. Inspired by the amount of people that were able to play the sims. I think that the low system requirments really helped their sales. As my game''s development has been moving along, scaling up for more eye candy hasn''t become a issue. I write the graphic code paths for old hardware and then move to the higher end machine (2700xp with Radeon9700) and implement the code paths for eye candy.

The only real issue that bothers me so much is the visual smack to the face that you feel going from a highly capable card with pixel shaders down to older hardware. So what I want is to be able to implement these high end features on the old cards and let the user turn them off for the speed gain. So they have them if they would like to see the game in it''s glory but realize that their hardware isn''t capable to run it realistically for play.

Hopefully my next project will be solely aimed at gamers with those high end cards of today in their computers. They say aim your game at hardware that people will have 2 years from now because that''s usually how long development time takes for most games. Which brings up an intresting topic about how games that have been in developement for over 4 years end up having to remake their graphics engines to keep up with the times.

~Wave

Share this post


Link to post
Share on other sites
quote:
Original post by Wavewash
Hopefully my next project will be solely aimed at gamers with those high end cards of today in their computers. They say aim your game at hardware that people will have 2 years from now because that''s usually how long development time takes for most games. Which brings up an intresting topic about how games that have been in developement for over 4 years end up having to remake their graphics engines to keep up with the times.


Case in point: Duke Nukem Forever. There have been no hard facts about this game for AT LEAST 2 or 3 years. But I''ve heard that they''ve had to redo their 3D engine twice (so that means they''ve gone through a total 3 engines) since the game has taken so damn long. Most people are convinced its vaporware by now anyway.

I agree with Wave. It seems that if you start developing a 3D engine right now with top of the line hardware, by the time a game that uses the engine is ready to ship most of your target audience will have hardware that should be able to play your game without too much trouble.

For example, if you start making an engine and game from scratch right now, I think it''s reasonable to expect that by the time the game is finished (1 1/2 to 2 years from now), the average gamer should have at least a DX9-compliant card. That doesn''t mean that grandma and grandpa will have one, but at least the average gamer should.

neneboricua

Share this post


Link to post
Share on other sites
I think that designing it for old hardware will help. You have to remember that most gamers aren''t rich, so they only buy new computers every three or more years. And the computers they buy aren''t top of the line. If you design a top of the line game now, by the time it is finished two or so years from now, the hardware will no longer be top of the line, BUT it won''t be common either.

--------------------------------------
I am the master of stories.....
If only I could just write them down...

Share this post


Link to post
Share on other sites
quote:
Original post by Nathaniel Hammen
If you design a top of the line game now, by the time it is finished two or so years from now, the hardware will no longer be top of the line, BUT it won't be common either.


That's exactly my thinking. Also my game takes a lot of inspiration from old sega and nintendo side scrollers (sonic and donkey kong country) I'm assuming that my target audience have played these games on these systems and now have either grown out of it or grown more further into games. Meaning I have this broad spectrum that I need the graphics tech to work with.

~Wave



[edited by - Wavewash on February 10, 2004 6:15:06 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!