   My attempt  at Shadow Mapping on Old Hardware (Results)
  //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 300clear backbuffer and depth bufferChange fog color to RedRender scene from 0 to 100Change fog color to GreenRender scene from 100 to 200Change fog color to BlueRender scene from 100 to 300and 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;LPDIRECT3DSURFACE8shadowtexS;LPDIRECT3DSURFACE8shadowdepthS;LPDIRECT3DSURFACE8 backbuffer;LPDIRECT3DSURFACE8 zbuffer;//get current infog_pd3dDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&backbuffer);g_pd3dDevice->GetDepthStencilSurface(&zbuffer);//create textureg_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 viewg_pd3dDevice->SetRenderTarget(shadowRegtexpointer,shadowdepthS);g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);//Render ObjectsLevelman.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 ObjectsLevelman.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]
  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 ;  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 ;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 ;  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... ;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]