- Home /
How to implement stencil shadows/shadow volumes
Hey all,
For the mobile game we are developing, we would like to implement shadow volumes to allow us to have point lights that cast shadows. Right now I have silhouette detection and shadow volume extrusion working. A separate GameObject is created for each shadow volume - I want to eventually do this all on the GPU, but this seemed like the most straight-forward way to get started.
This has been new territory for me and has left me with a few questions.
When "rendering" the shadow volume mesh to perform the stencil operations, do I render this at the same time as the scene, or do I have to render it after the full scene renders?
Once the stencil buffer is populated, how do I actually render the shadows? Do I have to use render textures? Do I apply some type of shader to the camera? Something else? Thank you for any help!
Answer by Bunny83 · May 20, 2016 at 06:53 AM
The order is usually as follows:
Render the scene normally
Render the shadow geometry with your shaddow shader which usually has two passes if you do "Carmack's reverse".
Render the "shadow" by rendering a fullscreen quad with your shadow colour with a special shader that does a stencil test.
I've once implemented stencil shadows in a C++ directX project and it worked pretty well.
ps: If you have trouble understanding how the depth fail algorithm works, i suggest reading this amazing letter of John Carmack where he describes the process of how he discovered it.
edit
The actual rendering can be done using one camera and use a queue offset in your shaders to make sure they are rendered after each other. The fullscreen quad could be rendered the same way or by using the GL class inside OnPostRender in a script attached to the camera. You can use pretty much the sample script that is shown in the docs.
ps: $$anonymous$$eep in $$anonymous$$d that your shadow geometry need to be "capped" on both ends. The easiest way is to split the original object into two parts across the shadow edge and use both halfs as caps. So you basically use the original mesh but extruding it at the edge by inserting some quads between the original edge loops of the caps.
Alternatively you could construct caps out of the edge information, but that's usually much more difficult and requires more performance.
If you're using shadow volumes just for 2d / 2.5d games you probably don't need caps as those are usually offscreen.
I still have a few kinks to work out, but I got it working overall.
$$anonymous$$y biggest hurdle was figuring out how to render it all to the screen which I accomplished through OnRenderImage which I'm surprised worked since I've seen other people had issue with stencil testing when doing that. Is there an advantage to one or the other?
Anyway, this helped immensely. Thank you!
Your answer
Follow this Question
Related Questions
Shadow Support in Custom Shader 0 Answers
Shadows don't render on materials with rendering mode set to "fade" or "transparent" 1 Answer
Shadows being received by non-shadow collectors that are depth culled by a shadow collector. 1 Answer
Render a sprite only when it's on the parent but not other sprites. 0 Answers
Stencil on iOS 0 Answers