Hm, so I don’t know why the bug occurs. Try to “deconstruct” (comment out more and more pieces of) your shader effect to see when it causes the shadow maps to appear/disappear. E.g. start by commenting out PLUG_material_metallic_roughness.
If this doesn’t help, I’ll need to see a testcase (like X3D model, maybe made by SaveNode) to reproduce the problem and fix
After my fix, one can add a test light source + test box to example_level_final.x3dv and the shadow maps will be OK:
# Examples how to add a light source that casts shadows.
SpotLight {
location 0 55 44
direction 0 -1 0
cutOffAngle 1
intensity 10
# Uncomment lines below to get shadow by shadow maps.
# See https://castle-engine.io/x3d_extensions_shadow_maps.php
# for a full documentation.
# In a very trivial cases, it's enough to just say "shadows TRUE",
# although you may want to adjust other settings.
projectionNear 40
projectionFar 60
shadows TRUE
defaultShadowMap GeneratedShadowMap {
size 4096
update "ALWAYS"
bias 4
scale 4
}
}
Transform {
translation 0 2 -10
children Shape {
appearance Appearance {
material PhysicalMaterial {
baseColor 0 0 1
emissiveColor 0.2 0.2 0.2
}
}
geometry Box { }
}
}
I don’t think the fix related to your case (if it would, then changing effect would not matter; only it would matter if you do ChangedAll or not on a scene). But to be sure, you can update the CGE, after above fix is build.
The weird thing is that the light doesn’t illuminate the trees or the water. The light and terrain are in their own scene/x3drootnode and all the trees are in another scene/x3drootnode. And the water in its own scene/x3drootnode.
These shadows look soo much better than the hard volumetric shadows. I am excited to get them properly looking good across the world. Time to get the moving sun into the new prototype. (also, the silhouette mode looks so cool with the terrain that is in the dark)
DirectionalLight works much better and is here working across multiple tiles each with their own DirectionalLight, but still not illuminating trees and water (which includes snow). It seems like x3d lights only light what is in the same x3drootnode? Is there a way to make them ‘global’ like cge lights?
If I turn on the cge directional light which does illuminate everything, it results in an interesting mix of the black and the color, like all the lakes are an oil slick. I don’t think the directions are aligned… in x3d the direction is a vector3 I have at (0,-1,-1) like a 45deg ray. in cge the direction is a vector4. I am not quite clear on how to make that match the vector3 rotation.
Ok, now I think the directional lights are aligned with vector4(1, 0, 0, -0.78 ). I halved the intensities and end up with close to what I had with nice subtle shadows. It would be nice to not have to have the extra light and just use those x3d lights. But I can live with this.
25000 trees on 5x5 tiles starts to get slow again, but still faster than 9000 trees with volumetric shadows. But I can stop using real trees at that distance and use the water/flora mesh. I only needed individual trees on the 3x3 tiles around you.
…
It was slower because have two clients and the server (flowing the water at 45 tiles per second on 145 tiles it has generated) running on the same old i7-4790K with RX580. So the performance is so far beyond my old prototype it is staggering. I might actually have room for a game:)
Giving the trees and water x3drootnodes their own x3d directional light gives better results than the ‘global’ cge directtional light without double lighting things. Shadows stand stronger and phong on terrain/snow is more pronounced since it isn’t mixing with black.
The X3D light node has Global set to true. By default (following X3D spec) it is false on TDirectionaLightNode, and true on TPointLightNode and TSpotLightNode.
Our high-level light components (TCastleDirectional/Point/SpotLight) present a more friendly API to this. But under the hood, TCastleDirectionalLight is really just setting up a regular internal TCastleScene instance, with TDirectionalLightNode instance, and makes sure that above is true (CastGlobalLights := true, FDirectionalLight.Global := true).
So you should be able to achieve the same result with lights in X3D nodes in TCastleScene, it’s just a bit more manual work. But I can see that the gain in performance and look is worth it Congratulations!
“Directions” are always 3D vectors in CGE, TVector3.
“Rotations” are 4D and expressed as axis+angle in general in CGE, as TVector4, first 3 components are axis, 4th is the angle (in radians) by which rotate around given axis.
(Except some cases when rotation is a quaternion, which is then clearly a TQuaternion).
TDirectionalLightNode.Direction is by default -Z
The TCastleTransform.Direction may be confusing, because it is an indirect way to set TCastleTransform.Rotation which in turn (when used on TCastleDirectionalLight instance) rotates the TDirectionalLightNode. So I can see that using Direction on TCastleDirectionalLight is not intuitive (it is not the direction in which light shines)… hmmm, added to TODO can we make it more intuitive (but any change here will have to be activated by new property, to not break backward compat).
Is the limitation requiring the light source be in the same x3drootnode as the shadow receiver likely to be resolved? I have too many issues with having each tile have its own local directional light. If I make them global then the whole scene blows out with too much light because they all shine on each other. I get issues now where a big mountains shadow at the edge of a tile won’t extend into the next tile. So feel pressed to move all the water and terrain meshes into the same x3drootnode which will be tricky because they all update independently and come and go dynamically as lod changes so are easier to manage as independent TCastleScenes. This effort seems unnecessary if that light-receiver limitation is temporary.
Another question is How can I avoid visual shadow flash (ie everything goes shadowed) for a frame when it updates the shadow map? Maybe I have to have two shadow maps and update and then replace it instantly? (I think maybe I just need to stagger the shadow updates per tile so they don’t all happen at the same time)
Yes , it will be resolved, that is one of the points (and a hard requirement for any other shadow map improvement) of the roadmap item about shadow maps that I mentioned. This limitation is temporary, I know how to solve it, it just needs my time to solve it
That is also a temporary problem, consequence of above. In the current way, we auto-calculate some things, and there’s really no “best moment” for this calculation. As the roadmap item above tells, we want to change the parameters to controls shadow maps.