Wow, something actually went quicker than I expected for a change! 😀Tonight I polished off the shadow caster elimination code I’ve had in my head for a while - previously the location of shadow casters was pretty basic - since obviously objects which are not in the camera’s frustum can still cast shadows into the view there is an issue of how you efficiently locate all objects which can be casting visible shadows.
I finally nailed some of the more annoying problems I’ve had on my TODO list - it turns out the lack of shadows when hardware skinning (which actually caused GL to crash in the driver - yuck), were due to a feature I put in, but forgot about. :/ I wanted to suppress the update of a shadow buffer to the hardware version when only doing the software vertex blend because of the shadow, because otherwise you would unnecessarily upload the buffer twice.
Manual meshes were not prepping for volume constructions properly, and there were some issues with prepping meshes which used shared vertex buffers for multiple components. These are now fixed. I still have a number of issues with animated meshes which I’m sure are related - that is the hardware skinning disappearing shadow problem, and the D3D9-fullscreen-software-blend glitch, neither of which I’ve been ableto explain despite detailed tracing through the code. I have also found that if I prepare an animated mesh for volume construction more than once, I get random crashes a few frames later, which suggests there is a buffer overrun somewhere.
I fixed another shadow visual glitch, where zpass and zfail volumes overlapped and caused artefacts, and squashed all the release mode-only crashes (I hate those). I’m now very happy with the stability and performance of my stencil shadows, although I have a number of optimisations yet to do which should primarily help with larger scenes. I’ve put my todo list up on the site so people can see what I have on my plate - as you can see I have a few more things on there left to do before I feel 0.
Well, after ruthlessly crushing the light cap problem underfoot, I now have what appear to be pretty darn stable shadows. I’ve had a couple of small problems, but I think they’re due to dodgy meshes rather than bad code - with volumes it’s very important that the mesh is completely closed. I’ve knocked off a few more items, namely 2-sided stencil support (which allows you to render ½ as many shadow volumes, which is nice), more config options, multiple light combinations and being able to turn off the shadows for each light.
They say the dark side of the Force is easier and more seductive; well, it turns out the same applies for shadow volume caps. 😀They’re needed whenever you enter the projection of the shadow volume (towards or away from the light), at the time when you need to use the ‘zfail’ volume rendering method (otherwise known as the Carmack method), because otherwise you can see out the ‘tube’ which is formed by the extrusion of the silhouette edges.
I’ve been slowly chipping away at the issues with shadows; I’ve resolved the majority of the issues with degenerate edges (those for which a second triangle cannot be found), and squashed lots of issues with animated meshes. I’m using modulative shadows as my test bed, here’s a screenshot I still have some issues to resolve, such as the use of 2-sided stencil operations (which allow you render the shadow volumes once instead of twice), zfail volume rendering, and GL which seems to be getting worse performance wise on nVidia right now.
Well, I’m finally back looking at shadows again, I got seriously distracted sorting out hardware skinning, because it turns out that there are several things that can throw it off kilter, like the fact that the GeForce4 does not support the UBTYE4 vertex element type (used for matrix indices), which is a bit naff if you ask me. Even my little Radeon Mobility supports that. I toyed with the idea of trying to deal with it, and tried a few options but they were all very hacky, or required much more vertex buffer memory than I was happy with, so in the end I decided not to support hardware skinning on cards which can’t handle UBYTE4 but can handle vertex programs, meaning that the prerequisite for hardware skinning is vertex program and UBYTE4 support.
Well, my buffer copy licensing scheme is working for software skinning, and hardware skinning based on vertex programs is also working a treat, including the changes required to GL to allow the binding of BLENDINDICES and BLENDWEIGHT vertex semantics. In release mode with 10 robots all animating independently, it amounts to almost a 50% speed increase when using vertex programs, and it’s probably more when the models are more complex since the robot doesn’t have a lot of vertices, so the ratio of effort between the bones (which are still CPU calculated) and the vertex blending which is now accelerated will be more marked in bigger models.
I seem to be getting sidetracked an awful lot while doing this shadow work, more than is usual even for me. The fact is that there are a few things I’ve been meaning to change for a while, and they are going to affect the shadow work anyway, so I figure I might as well get them done now. I’m currently implementing a ‘buffer copy licensing’ scheme where objects can ‘lease’ temporary vertex buffers which have the same attributes as another buffer, used for working storage for things like skeletal animation.