The scene is rendered without any lighting and textures and materials turned off by a camera placed at the lights position and pointed at the center of the screen onto a “Shadow” buffer. The buffer has a black background, and objects are rendered solid white. The ground is not rendered. The buffer is blurred using CommonFilters, then its texture is captured and projected back onto the scene from the cameras position and rotation.
This projected texture is applied using the blend mode, which makes anything white look dark on the ground, and black pixels are see through.
But that will not create shadows. That will just illuminate how far the first pixel is from the light source. You cant blurry without shaders.
But you can do shadows without shaders using stencil shadows, but they are quite slow and require special closed hull models from your art team. And the math to get them to work is insane! Doom3 uses this shadow type.
It’s that blurring step that’s going to kill you. If you’re not using a shader, that means you have to blur the texture on the CPU, which means you have to copy the texture RAM from graphics memory to main memory and back again, and that double-copy is death to your frame rate. Plus the CPU isn’t as good at that kind of processing as the GPU is, so you get a double hit.
It would probably be better to use an on-card approach to soft shadows, rendering multiple different (slightly offset) views from the light onto the same texture, blending them sensibly. But this means multiple rendering passes over the scene, which can again be a killer if your scene is complex.
You can certainly use this technique to create shadows without using a shader, if you’re content with hard-edged (and slightly pixelly) shadows. The code in direct/src/showbase/ShadowDemo.py demonstrates precisely this.
That works really good. I’ve got ~30fps on my really, really bad machine, and with a bit of tweaking I got it to run at ~60fps (so at top speed). I’ve set the buffer size 256x256 and setBlurSharpen(0.0). The shadows are more blurry (softer) and it runs faster.
I have no idea why people in this thread were so sceptic. It works perfectly. Besides the usual error messages on the console it looks perfect, just with low FPS (9-10). Playing with the buffer size or blurSharpen doesnt improve things.
The original topic was edited after we had posted our suggestions. Our skepticism was directed at the original suggestion to blur the texture without using shaders. The final implementation does use shaders, which is a fine solution.
On a different note, I actually get amazingly good performance with this code. It tops 700 frames here, and the shadow looks very good. The only problem is that when I uncomment setShaderAuto(), the framerate drops to ~70-80 frames. Can’t say I understand where such difference comes from.
I think there is a bug in Panda that is killing the frame rate when a projected texture is used along with the shader generator.
There is one bug in this code; if you have an model under the ground it will still show up as a shadow. I suggest using a clip plane on the shadow camera to make everything under the ground invisible. This should not be a common problem though, as I see no reason to place a model under the floor.
One way to work around this bug is to save out the generated shader into a file, and then load it explicitly and apply it to your model instead of enabling the auto-shader. You do have to do this separately for each part of your model that has different states, though.