![]() |
![]() |
![]() |
![]() |
(Yes, it’s a 3rd news about Castle Game Engine in 3 days. More to come — we have a backlog of things to announce! Brace yourselves 🙂 )
We introduced an algorithm to detect 2-manifold scenes better, meaning that all scenes that are really 2-manifold (even if not all shapes inside are 2-manifold) are automatically shadow casters for shadow volumes.
This improves shadow volumes usage experience. You no longer have to mark such scenes with TCastleRenderOptions.WholeSceneManifold
.
OK, I can see that the above description, while correct, may be confusing if you’re not familiar with how shadow volumes work. Let’s unpack this slowly 🙂
- Shadow volumes is one of the algorithms to achieve shadows using Castle Game Engine. It’s right now the simplest one to use, you only need to have 2-manifold models and then flip the
Shadows
checkbox at the light source totrue
.- Note: The “simplest shadows algorithm to use” award will likely change to shadow maps in the future, once we implement a few improvements to it. See also recent news post about shadow maps plans.
-
But even then, both algorithms (shadow volumes and shadow maps) will remain useful and available and in our engine. They both have their advantages and disadvantages (how shadows look, performance and possible optimizations, what is valid shadow caster…).
-
For shadow volumes, only 3D objects that are 2-manifold can cast shadows. 2-manifold means that each edge has 2 neighbor faces. This is the most natural state for 3D models that represent real things, that have a volume and are watertight, though in practice many 3D models have only most edges with 2 neighbors. The shadow volumes algorithm strictly requires that all the edges of things that cast shadows have 2 neighbors.
-
We allowed already 2 ways to cope with 2-manifold requirement: either make all shapes 2-manifold, or use
TCastleRenderOptions.WholeSceneManifold
to treat whole scene (unchecked) as 2-manifold.- BTW, what is a “shape”? Shape is part of the scene, the simplest unit passed to the GPU.
- In glTF, it’s a primitive.
- n Blender, it’s a subset of Blender’s object with a single material.
- In X3D, it’s literally the X3D
Shape
node, loaded toTShapeNode
instance in our engine.
- BTW, what is a “shape”? Shape is part of the scene, the simplest unit passed to the GPU.
The new improvements means that you don’t need to touch TCastleRenderOptions.WholeSceneManifold
if the scene is already 2-manifold.
Now, using the TCastleRenderOptions.WholeSceneManifold
is only necessary if:
- You want to force the scene to be shadow caster for shadow volumes, even if it was not detected as 2-manifold, Beware that rendering artifacts are possible in this case. However, we did find a number of cases when this forcing actually works properly (at least for the camera position/orientations that mattered in a given demo), despite scene not being a correct 2-manifold.
-
Or if you just want to speed up loading. Marking scene as
TCastleRenderOptions.WholeSceneManifold
avoids any automatic detection, the appropriate check “passes automatically”.
We took care to check that this auto-detection doesn’t cause any issues:
- We checked it doesn’t cause unnecessary slowdown. We time it, showing in log if it would take more time > 0.01 sec (it never did in our tests).
-
We checked it doesn’t cause problems due to per-shape
TCastleScene.DistanceCulling
being disabled on scenes that are 2-manifold, but when shapes are not 2-manifold. The per-shapeTCastleScene.DistanceCulling
check is now really only done when shadow volumes are used, and scene is shadow caster, and whole scene is 2-manifold (but some shapes are not 2-manifold).
We have updated example on examples/viewport_and_scenes/shadow_volumes_whole_scene_manifold, along with README description and screenshots inside. Part of this demo now works “out of the box”, alpaca model is automatically a shadow caster.
We also updated documentation about shadow volumes. Many things have been upgraded, and naturally the section about 2-manifold objects (when they are detected, and when is RenderOptions.WholeSceneManifold
useful) has been rewritten to reflect the current state.
We also updated the Castle Model Viewer menu “Help -> 2-Manifold Information (Shadow Volumes Casting)”. New colors of edges:
- yellow: manifold edges in the same shape, so this edge connects 2 faces within the same shape.
- white: manifold edges in the whole scene, so this edge connects 2 faces from different shapes.
- blue: border edge that doesn’t have 2 face neighbors. If you have this, this scene cannot be (reliably) a shadow caster for shadow volumes, because it is not 2-manifold.
Testing shows that this detection makes sense in many cases (and avoids you having to toggle dangerous TCastleRenderOptions.WholeSceneManifold
) but also it fails in many cases (so TCastleRenderOptions.WholeSceneManifold
still has a use-case, there are often no noticeable artifacts despite model not being 2-manifold).
- Examples where the new detection doesn’t help (
TCastleRenderOptions.WholeSceneManifold
still is necessary):- physics_throw_chickens demo, both bull and chicken need
TCastleRenderOptions.WholeSceneManifold
- split_long_animation
- creature_behaviors
- cpp_builder/window
- delphi summit 2025 game controllers demo (some models)
- physics_throw_chickens demo, both bull and chicken need
- Examples where the new detection helps (so shadow volumes are automatically ok):
- multiple_viewports (raptor)
- shadow_volumes_whole_scene_manifold (alpaca)
- shadows_distance_culling
- delphi summit 2025 game controllers demo (some models, like columns).
All in all, testing shows it’s a benefit, and doesn’t have any drawbacks 🙂
Sadly, it doesn’t mean we can get rid of TCastleRenderOptions.WholeSceneManifold
(it would be nice to get rid of this dangerous checkbox, but it still makes sense).
Test it on your own projects and let us know (e.g. in the comments on the forum) how it works for you!
And if you like this work, please support us on Patreon. Thank you!