I’ve been working on a new and improved Shadow Volume SceneProcessor based on the JME2 one, with a few improvements.
- New: More/better Caching (caching some stuff per Mesh, and others per Geometry
- New: Support for inefficient shapes (i.e. ones with edges that share coordinates but do not share indexes)
- New: Works in JME3 (80% of the old code has been modified, rewritten, or is new)
- New: Trivial to use (just 2 lines of code to add the scene processor)
- New: Surface bias to make it look better
- New: No issues with being inside of the shadow (modified z-fail)
- Trivial to use (rootNode.setShadowMode(ShadowMode.CastAndReceive);)
- No aliasing
- Requires my StencilBuffer addition to RenderState
- Coming soon: optimized shadow volumes for spheres
Note: The two existing shadow methods (Basic and PSSM) are likely better for most game applications: high poly count, high numbers of lights, anything with moving lights, or large numbers of moving objects, and anything with partially transparent shadow casters, but worse for other applications: distant shadow casters, large static scenes, surface-self shadowing (at least until biasing is properly used in them- the demos don’t seem to use it), and other specific cases.
In my case I want to do space scenes with relatively few objects, at relatively large distances, so shadow volumes work well and look good.
Based on the PSSM Test:
(Note, framerates are lower than they could be because I have moving objects in the scene)
Here is the code for the ShadowVolumeRenderer:
main.java is the test file.
If you have any comments, questions, or concerns let me know
A note on the usage of z-fail: The patent specifically requires incrementing the stencil on back face depth fail, and decrementing on the front face. My code does the opposite: it decrement-wraps on back face fail, and increment-wraps on front face fail. Additionally this is done in one step using new two sided stencil buffer functionality in OpenGL 2.0. To my knowledge this implementation is non-infringing, however it’s trivial to modify it to z-pass, although that reintroduces camera placement issues.
Good job! By the way, does it handle multiple lights? How about point lights?
The primary issue with Basic and PSSM shadows is that they only support a single directional light, this makes it very difficult to use them for indoor terrains.
Multiple lights should work just fine, update speed is linear with the number of lights based on the code… let me actually test that :P
Two directional lights:
As you can see, I’m only doing one stencil pass for all shadow volumes, so shadows are not additive. I should probably make it an option to do multiple passes (boolean), because I can think of times when you’d want one or the other.
A point light (not quite working yet)
This demonstrates a directional light. The code I had up in the repo this morning didn’t support point lights, but only because I had some debugging stuff forcing all lights to be directional. I’ve changed the 2-3 lines and pushed the changeset to bitbucket, but as the screenshot kindof shows, something’s screwing up with point lights, although it’s very clearly nearly functioning. To be honest I had intended to support them, but entirely forgot about it, so the fact that it works at all is nice. I suspect that I’m miscalculating something to do with them that will be fairly easy to discover.
Out of intrest, how are multiple static shadow volumes are handled? Are the batched into one larger ? As the only problem I see is the possibility of havig to mcuh objects.
However since I’m working on a space game too I’m really intrested in this.
(Shadowvolumes for static objects and ppsm or dynamic might be a fast solution, at least I hope)
Shadow volumes are handled like this:
- Edge/face geometry created the first time a Mesh is used and then reused every time a model using that mesh is created by ShadowVolumeRenderer. (This is the most expensive part of creating the shadow volumes).
- GeometryShadows caches Geometry and Light transforms on a per geometry basis, and caches the shadow volumes for each shadow of the geometry (via the ShadowEdge ShadowTriangle and ShadowVolume classes). These are updated whenever something moves basically. If a light moves then all of the shadow volumes created by that light are updated, while if an object moves, just that object’s SV is updated. There is code from the JME2 version for throttling updates but I don’t think it works quite yet.
Having a large number of static objects and static lights shouldn’t be a problem, but if you had more than about 20 high poly count objects (most space ships probably don’t count) things might get slow.
As for running both shadow renderers, it’s possible with minor changes but JME3 doesn’t really have a way of choosing one technique over the other on a per model basis at the moment. It wouldn’t be hard to implement though.
hey nice work!
That’s good to have an alternative to shadow mapping or pssm.
Thank you for sharing this, we definitely gonna add it to the core.
Glad to hear it. I’m just going to see if I can get point lighting to work. The project that I needed Shadow Volumes for has been put on hold so I figured that I might as well just try to get my work out there so that it doesn’t go to waste. Once I’m happy with it (eta one week most likely) I’ll create a post in the contributions forum for it
Any more recent news on this? I’d love to have access to a shadowing technique that doesn’t result in all-parallel shadows and can handle multiple light sources. I was more than a little shocked / disappointed when I discovered that JME3 didn’t support something like that already.
Does this technique work correctly with transparent / translucent objects?
I was more than a little shocked / disappointed when I discovered that JME3 didn’t support something like that already.
Must have been soooo hard for you, we are so sorry…..
Well you can contribute your own shadow renderer we’ll be glad to add it to the core…
Well I’m sorry too, never mind ;)
In fact directional shadow mapping works fine for wide area and I think it’s the most used shadow technique. That’s why once it was implemented we relied on it.
But shadow mapping for point lights is definitely planned too.
Also this shadow Volume renderer will be added to the core pretty soon, I don’t know if it works for transparent materials though.
Hmm…as another question, is it possible to combine shadowing techniques? Say for example you have a character carrying a torch (point light) at dusk. You’d probably want to use a directional light + PSSM for the sunlight, but you’d also want to use point light + shadow volumes for the torch. Would the two play nicely together?
I ask because I actually have very little background in how 3D rendering works, so despite reading the papers on PSSM I have no idea how it works.
It should, but honestly, it has to be tested.
One thing to know though is that dynamic shadows are expensive, if you have this kind of scene, with dark corridors, consider using light maps (pre baked shadow maps) for the scene and dynamic shadows for the point light.
You must be logged in to reply to this topic.