# Shadow maps in 2025?

**URL:** <https://forum.castle-engine.io/t/shadow-maps-in-2025/1923>\
**Category:** Uncategorized\
**Created:** [May 27, 2025, 6:43pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923 "2025-05-27T18:43:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 27, 2025, 6:43pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/1 "2025-05-27T18:43:08Z")

</div>

In 2023 you mentioned that I might use shadow maps but it would be difficult. I am been trying to figure out how to use those in hopes they perform nicely with many trees. It is confusing disentangling the documentation for shadow maps vs shadow volumes. It seems like they overlap with some things? Like shadows boolean? It seems like the docs for shadow maps are more at the x3d level? Has anything changed on shadow maps? I switched to DirectionalLight instead of Pointlight, but still see no shadows. My objects are all built in pascal, nothing comes from blender or file models. I guess I need to add the shadowmap to map terrain triangle sets?

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 27, 2025, 7:37pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/2 "2025-05-27T19:37:01Z")

</div>

I tried the castle\_with\_trees\_process in the shadow\_maps demo models… but it won’t build, it can’t find FdProjectionNear in a TAbstractLightNode.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 27, 2025, 11:04pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/3 "2025-05-27T23:04:17Z")

</div>

Making shadow maps really comfortable is still a TODO, see [roadmap section about shadow maps](https://castle-engine.io/roadmap#shadow_maps). I did a progress there (to make cross-scene), but it’s all still work-in-progress I’m afraid.

That is, shadow maps work, but are not as comfortable as I’d like, you need to have everything in one X3D scene, which pretty much prevents the normal engine usage (when you have many scenes, and I recommend it). Which is likely making it not really useful in your case, sorry – it’s one of tasks blocking 7.0, so I really want to clean it up + improve.

Docs:

- Shadow maps docs are on [Shadow Maps | Castle Game Engine](https://castle-engine.io/x3d_extensions_shadow_maps.php) .

- They are separate from shadow volumes [Shadow Volumes | Manual | Castle Game Engine](https://castle-engine.io/shadow_volumes) .

Sorry, cleaning up the mess above is part of our roadmap item 🙂 I know that shadow maps are at this point hard to use.

> [@edj](#):
>
> I tried the castle\_with\_trees\_process in the shadow\_maps demo models… but it won’t build, it can’t find FdProjectionNear in a TAbstractLightNode.

We moved some properties to `TAbstractPunctualLightNode`. I fixed that tool (see [Fix compilation of castle\_with\_trees\_process.lpr · castle-engine/demo-models@4bc94f7 · GitHub](https://github.com/castle-engine/demo-models/commit/4bc94f7d8ba81068883e8fd992a25010b6620246) ) and made sure it produces the output as before.

But you should not need to use it, in practice. That tool converts VRML generated by old Blender-\>VRML exporter (the current Blender X3D exporter is likely quite different). The whole example should be, frankly, remade to use [glTF (model format) | Creating Game Data | Castle Game Engine](https://castle-engine.io/gltf) now which has excellent Blender-\>glTF converter and we recommend it.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 27, 2025, 11:27pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/4 "2025-05-27T23:27:39Z")

</div>

I can easily put the terrain and the trees into the same x3d rootnode. Then the trees can cast shadows without the huge performance expense they do with the volume shadows. It already seems beneficial to have all the trees for a tile in 1 x3d rootnode. I have to have the light in the same scene too? Perhaps if I duplicated the light per tile (ie per scene) for just shadow use?

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 28, 2025, 9:14am UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/5 "2025-05-28T09:14:22Z")

</div>

Various answers:

- Currently, the shadow receiver and the light casting shadows must be in the same scene. It doesn’t matter where the shadow caster is, it can be in different scene.

- There is no concept of “light just for shadow use” for shadow maps. “Shadow” means (in a simulation of shadow maps and in reality 🙂 ) that a light doesn’t reach the object. So the light must really shine to make the shadow sensible.

- I don’t really recommend to merge many things together in 1 scene with 1 X3D root node. We want to optimize world with many scenes, not with 1 big scene, though some things work better this or that way. In practice, a “healthy mix” works best, see [Optimization and profiling | Manual | Castle Game Engine](https://castle-engine.io/manual_optimization.php) . If you have a case where just combining 100 TCastleScene instances into one TCastleScene instance with one X3D graph makes it much faster → submit a bug with a testcase to reproduce, because usually it should not make a big difference (unless you do something more at merging).

- It would be bad if you are forced to merge into one scene by our unoptimal shadow maps implementation. I feel that our problems in the shadow maps area really should not guide this design decision how you use CGE, as it will affect many things 🙂 We should just improve shadow maps on the CGE side.

All in all, I’m afraid it will be complicated to setup for you, and the gains are not that obvious. Shadow maps also have a performance hit, just in a different place. And they look much different.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 28, 2025, 2:28pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/6 "2025-05-28T14:28:03Z")

</div>

It seems like having lots of trees in one scene is helpful. In this case 1000 trees in a scene. I feel like shadowmaps is ideal since trees don’t move so they would only need to be calculated every few minutes as the sun moves. But I can wait til it is more ready. I have been trying to get the core basics nailed down before moving on to other things (revisiting roads). If I have just 100 trees per tile, even with shadows, performance is ok. I can live with that for now. If you do have time to revisit shadow maps, a demo that applies them in wyrdforest or to the terrain demo would be cool.

You are of course welcome to try the repo. Right now it is set to 1000 trees per tile, all in their own scene.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 28, 2025, 5:38pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/7 "2025-05-28T17:38:31Z")

</div>

> [@edj](#):
>
> In this case 1000 trees in a scene. I feel like shadowmaps is ideal since trees don’t move so they would only need to be calculated every few minutes as the sun moves.

Right, this would indeed be a gain, shadow maps are updated only as often as you want. In frames when shadow maps don’t need to be updated, their cost is merely an additional texture fetch per light source, so rather trivial.

For shadow volumes, they have to be rendered (shadow quads, and 2nd pass with light) every frame.

> [@edj](#):
>
> But I can wait til it is more ready.

I think I indeed advise it (to wait) in this situation. I would hate to see you redesign your approach (as merging/splitting TCastleScene has an effect on how you do other things you can do in CGE, so it’s not something trivial to undo in general) to address our problems with shadow maps, which will hopefully just disappear in 2025.

> [@edj](#):
>
> You are of course welcome to try the repo. Right now it is set to 1000 trees per tile, all in their own scene.

Thank you! I added this to TODO.

---

<div class="post-metadata">

**Author:** ![kagamma](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/kagamma/32/226_2.png) [@kagamma](https://forum.castle-engine.io/u/kagamma)\
**Post date:** [May 29, 2025, 1:26pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/8 "2025-05-29T13:26:42Z")

</div>

From what I see shadow volumes also scale quite poorly on modern monitors with very high resolution, since the same scene need to be rendered 2 times on the same display buffer.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 1:34pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/9 "2025-05-29T13:34:52Z")

</div>

Yeah, that is why I am hoping shadow maps will be the ultimate solution for trees and immobile stuff like buildings.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 2:19pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/10 "2025-05-29T14:19:54Z")

</div>

So the summary is Shadow Maps work now with shadow caster and shadow receiver in the same x3drootnode. But I also have to add a light in the x3d (not cge lights whose shadow settings are all for volume shadows) that has a shadowmap x3d node. But the light can be outside of the caster/receiver’s x3drootnode. And then I do something when I want to trigger the shadows to be recalculated? Am I missing anything?

That sounds pretty doable. I already do more in x3dnodes than I do with the higher level cge classes. Shadows do a lot to give the terrain visual depth and topography. Especially when terrain casts shadow on itself in low sun.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 29, 2025, 4:49pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/11 "2025-05-29T16:49:29Z")

</div>

> [@edj](#):
>
> So the summary is Shadow Maps work now with shadow caster and shadow receiver in the same x3drootnode.

No, that’s not what I wrote in [Shadow maps in 2025? - #5 by michalis](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/5) 🙂 To recap, I wrote:

> Currently, the shadow receiver and the light casting shadows must be in the same scene. It doesn’t matter where the shadow caster is, it can be in different scene.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 5:32pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/12 "2025-05-29T17:32:36Z")

</div>

Ok, thanks, I misunderstood.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 29, 2025, 5:32pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/13 "2025-05-29T17:32:51Z")

</div>

Potentially useful example of setting up shadow maps is [castle-engine/examples/research\_special\_rendering\_methods/test\_rendering\_opengl\_capabilities at master · castle-engine/castle-engine · GitHub](https://github.com/castle-engine/castle-engine/tree/master/examples/research_special_rendering_methods/test_rendering_opengl_capabilities) .

Note that it tests a few things, also shadow volumes in the same world as shadow maps. This is where shadow maps are visible:

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/2/21861689a4da50093f04dd6d017b6bf6958c5349.jpeg)

You can experiment in editor to confirm what I claim above,

> Currently, the shadow receiver and the light casting shadows must be in the same scene. It doesn’t matter where the shadow caster is, it can be in different scene.

- So the light source and shadow receiver must be in 1 scene (`castle-data:/primitives_with_shadow_maps.x3dv` in that example).
- Shadow caster can be anything in that world. Below I added TCastleCone, and it casts shadows using shadow map too.

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/7/78419cf29fa5bd3f972bd1da3b45dd38bac2a274.png)

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 6:08pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/14 "2025-05-29T18:08:29Z")

</div>

Cool, I see the shadowmaps in that demo with the Sometext. I see in the x3dv file the

```auto
DEF Light SpotLight {
  location 0 2 0
  direction 0 -1 0
  shadows TRUE
  cutOffAngle 0.6
  defaultShadowMap GeneratedShadowMap { update "ALWAYS" size 1024 }
}

```

How would I do that with the x3d nodes in code, or is there a way to parse snippets of x3d code when building the x3drootnode? I see the definition for the SpotLight X3DLightNode and shadows boolean but I don’t see a field for the defaultShadowMap.  
…  
Ok, found Light.FdDefaultShadowMap. So I can set that to a GeneratedShadowMap and should be able to maybe see something. Or maybe I need to set something in the terrain and in the trees still.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 7:06pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/16 "2025-05-29T19:06:55Z")

</div>

Now I have my Spotlight defined in the same x3drootnode (scene) as the terrain tile it is in. I can see its ring. Here is the code added where it is building the tile…

```auto
   Shape := TShapeNode.Create;
   Shape.Geometry := Triangles;

   Light := TSpotLightNode.Create;
   Light.Attenuation := vector3(0,0,0);
   Light.Radius := 200;
   Light.Location := vector3( 0, 10, 0 );
   Light.direction := vector3( 0, -1, 0 );
   Light.Shadows := true;
   Light.Intensity := 20;
   Light.CutOffAngle := 1;

   Appearance := InitAppearance;
   Appearance.ShadowCaster := true;
   Appearance.SetReceiveShadows([Light]);
   Shape.Appearance := Appearance;

   shadowmap := TGeneratedShadowMapNode.Create;
   shadowmap.Update := upNextFrameOnly;
   shadowmap.Size := 1024;
   Light.DefaultShadowMap := shadowmap;

   Root := TX3DRootNode.Create;
   Root.AddChildren( Shape );
   Root.AddChildren( Light );          

```

Then in the tree builder I add `shape.Appearance.ShadowCaster := true ; `  
But I still don’t see them. Am I missing a step?

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/6/6e6ff5ac0016809716bc8ee8c83d04826f85237b.jpeg)

---

<div class="post-metadata">

**Author:** ![DiggiDoggi](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/d/6a8cbe/32.png) [@DiggiDoggi](https://forum.castle-engine.io/u/DiggiDoggi)\
**Post date:** [May 29, 2025, 8:01pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/17 "2025-05-29T20:01:37Z")

</div>

> [@edj](#):
>
> `shadowmap.Update := upNextFrameOnly;`

Maybe try upAlways? In the PostUpdate method, the upNextFrame thing is set to upNone. So it may happen that your trees aren’t ready yet

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [May 29, 2025, 8:40pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/18 "2025-05-29T20:40:26Z")

</div>

There are some parameters, like projection near/far, that need to be adjusted for shadow maps to look right – see [Shadow Maps | Castle Game Engine](https://castle-engine.io/x3d_extensions_shadow_maps.php) . We try to auto-calculate them, but it’s not fool-proof, and it likely goes wrong for non-trivial large worlds. Which is again something we plan to improve, likely by resigning from auto-calculation and just giving you more intuitive options to control them, see that [roadmap item](https://castle-engine.io/roadmap#shadow_maps).

In general, I would say to make a test on a simple isolated scene. One piece of terrain, one tree, just one X3D model, that can be investigated e.g. in castle-model-viewer on even text editor.

- It will either work (and you will have a starting point),
- or you will have a testcase to submit here so we can investigate 🙂

Remember you can dump your X3D node graph using `SaveNode`.

> [@edj](#):
>
> `Appearance.SetReceiveShadows([Light]);`

Note that there’s no point in doing both `Appearance.SetReceiveShadows([Light]);` and `Light.Shadows := true;`. See [Shadow Maps | Castle Game Engine](https://castle-engine.io/x3d_extensions_shadow_maps.php) ,

_This is equivalent to adding this light source to every shape’s `receiveShadows` field. Read on to know more details._.

> [@edj](#):
>
> `Appearance.ShadowCaster := true;`

This is also not necessary, things are shadow casters by default, see [Shadow Maps | Castle Game Engine](https://castle-engine.io/x3d_extensions_shadow_maps.php#section_shadow_caster) ,

_By default, every `Shape` in the scene casts a shadow._

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 9:48pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/19 "2025-05-29T21:48:03Z")

</div>

It is working. It was working but the light direction seems to have insured no shadows. I turned off other lights and angled the light at 45deg toward the 0,0 of the tile (here just 1)… and I see some shadows. I should use direction light because this is ‘sun’

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/7/75f166572530f90e74d27a6eb494e4a7a93dad86.jpeg)  
I like the softer edges of these shadows compared to volumetric shadows.

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 10:01pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/20 "2025-05-29T22:01:08Z")

</div>

Hmm. That is casting the shadows on the water, but not the terrain. The water and terrain are related classes. But the water uses texcoords and a texture image, while the terrain uses an effect that is based on the terrain.fs used by tcastleterrain. Would this affect shadow map behavior?

---

<div class="post-metadata">

**Author:** ![edj](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/edj/32/1701_2.png) [@edj](https://forum.castle-engine.io/u/edj)\
**Post date:** [May 29, 2025, 10:25pm UTC](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923/21 "2025-05-29T22:25:42Z")

</div>

If I disable the effect so the terrain is just white material then I do see the shadows. How can I made shadow maps work with the glsl shader? Maybe I need to pass the shadow map into the shader and mix it in?

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/6/6be7f4fcaab4124704f17a56ba8d058f9ce5283d.jpeg)

[Next page](https://forum.castle-engine.io/t/shadow-maps-in-2025/1923.md?page=2)
