Hi,
I have placed two scenes. One with DistanceCulling = 0 and one with DistanceCulling = 100.
When the DistanceCulling starts, the scene (left house) becomes invisible, but the shadow is still visible.
Maybe a bug?
regards
Dieter
Hi,
I have placed two scenes. One with DistanceCulling = 0 and one with DistanceCulling = 100.
When the DistanceCulling starts, the scene (left house) becomes invisible, but the shadow is still visible.
Maybe a bug?
regards
Dieter
Fixed, thank you for reporting!
I have already committed the fix, Do not render shadows for objects eliminated by DistanceCulling · castle-engine/castle-engine@6081eaa · GitHub . It will be available in binary CGE downloads ( Download | Castle Game Engine ) in ~6 hours, once Jenkins builds new CGE.
Indeed, we should not render shadows for invisible objects.
Not only it looks a bit weird…
… but in case of shadow volumes it is actually a bug: the calculation of shadow volumes assumes that shadow caster is really rendered, otherwise weird things may be visible.
I tested on a quickly hacked version of “3D FPS game” template, here are screenshots before and after.
Note: The “shadow maps” algorithm, that I will want to expose in the future, will actually enable to render shadows for invisible objects. We can have it as an option then (but still, by default off, so we will not render shadows from invisible objects).
Hi Michalis,
I have the same issue with the newest version.
Can you check please if you get the same result?
Thanks
Didi
We had indeed changes related to shadow volumes recently ( Shadow volumes: new WholeSceneManifold option, fixes and docs – Castle Game Engine ) so it is feasible I broke something.
… However, testing, it seems everything is OK. I tested:
modified “3D FPS game” (with DistanceCulling = 10)
I also added examples/viewport_and_scenes/shadows_distance_culling
and tested it.
I actually found one small issue ( LocalRenderShadowVolume must update RenderCameraPosition · castle-engine/castle-engine@97f98fb · GitHub ) but I doubt this is your issue – it could cause 1-frame delay, not a constant invalid shadow.
Can you submit an exact testcase to reproduce your problem? Or maybe you can modify examples/viewport_and_scenes/shadows_distance_culling
to cause it?
Note that I just added examples/viewport_and_scenes/shadows_distance_culling
to the repository, it will take a while for Jenkins to update the binary builds. When this page : Comparing snapshot...master · castle-engine/castle-engine · GitHub will no longer show commit " Test shadows and DistanceCulling", then it is incorporated in the build on Download | Castle Game Engine .
I have seen now, that it happens only when WholeSceneManifold is TRUE.
But in my case i need this.
Is it possible to check if the scene is visible? When not visible I can set WholeSceneManifold to false?
Regards
Didi
Confirmed, the case of WholeSceneManifold
combined with DistanceCulling
is not good now. I had a TODO to improve it – I’m working on it (I kind of have a fix, but it doesn’t work fully yet ).
I’ll let you know, maybe even today later I’ll finish it.
Still in progress.
I found the mistake in my reasoning about how the WholeSceneManifold
should interact with per-shape culling (like done by DistanceCulling
). It’s a bit larger change, so I’ll finish it later, hopefully tomorrow.
For today I committed my current solution – it behaves better than before, but it is not fully correct (when the DistanceCulling
distance radius is inside the house, right now part of it will be rendered, part not; but when WholeSceneManifold=true
we have to always render whole house).
I also extended the testcase examples/viewport_and_scenes/shadows_distance_culling
to include test of WholeSceneManifold=true
(I use house model with a few materials, such that it requires WholeSceneManifold
).
More to come tomorrow
All properly fixed.
WholeSceneManifold
cooperates now with DistanceCulling
properly always.
I tested various cases in examples/viewport_and_scenes/shadows_distance_culling
.
As usual, please test and let me know is it good now in your case
The fix is committed to GitHub master branch. You can observe this page: Comparing snapshot...master · castle-engine/castle-engine · GitHub . When it will no longer contain commit " Fix (and simplify) cooperation between WholeSceneManifold and Distanc…" then it means this fix is incorporated into builds on Download | Castle Game Engine .
Hi Michalis,
WholeSceneManifold with use of DistanceCulling looks very good now.
Performance is also still good.
In my new project i use in the moment 50 scenes (12 with WholeSceneManifold), three big Terrains and a lot of TCastleTransform.
TreeTransforms: array [1..50] of TCastleTransform; (with shadows)
Tree2Transforms: array [1..20] of TCastleTransform; (with shadows)
GrassTransforms1: array [1..1600] of TCastleTransform; (with move animation)
FlowersTransforms: array [1..500] of TCastleTransform;
RockTransforms: array [1..50] of TCastleTransform;
FPS is between 20 to 30.
some questions:
Why does DistanceCulling depends on the Scene.Scale? It would be easier to set DistanceCulling on more scenes with different scales, if the value were to be calculated on a uniform basis (e.g. Scale = 1)?
Visibility is not inherited between parent and child. I use a scene as parent and TCastleBox as child, and a TCastleText as child from the box. If the scene is not visible (because of DistanceCulling) the box and the text are still visible.
The child scene1 or scene4 (weapon) of a parent scene (avatar) has no shadow. All of these scenes are set up for shadow.
I use this to change the weapon:
Regards
Didi
Hm, these are both features resulting from current design – although I agree that the design is not the most comfortable
DistanceCulling
is a property of given TCastleScene
. So it is interpreted in the “local coordinate system” of this scene (scaling the scene scales also the DistanceCulling
interpretation, in a way). This is consistent with some other things – in general distances and calculations are done in local coordinate system of given TCastleTransform
.
I agree this is not most comfortable in this case. Since you have to edit DistanceCulling
on each scene, you’d like to select a bunch of scenes in editor, and edit their DistanceCulling
at once, but you cannot if their scales differ.
And the 2nd fact, that DistanceCulling
is on each scene (and doesn’t affect children), is consistent with the fact that TCastleScene
specific features (like TCastleRender
) do not affect children (because in general case, this would create more questions and difficulty for implementation - e.g. scene RenderOptions
or ReceiveShadowVolumes
also do not affect children).
Although most properties on TCastleTransform
, like Exists
, do effect children. E.g. CastShadows
do work recursively. I know, the end result isn’t perfect (esp. making ReceiveShadowVolumes
and CastShadows
not consistent), but at least there’s a rule to the madness – stuff on TCastleTransform
is usually recursive, stuff on TCastleScene
is usually not.
I think there is one solution to both these issues: we need a system to apply a distance culling on a group of objects. So you would apply it one place, e.g. a TreeGroup: TCastleTransform
, and then all 50x TreeTransforms
are just children of it, and they are automatically affected. Such distance culling would be specified in the local coordinate system of TreeGroup
, and then the scaling specific to each particular tree should not matter.
We could do this by implementing TCastleBehavior
that synchronizes DistanceCulling
on all scene children.
I did a quick attempt at this – see Behavior that affects all children scenes, setting their DistanceCulling (TDistanceCullingGroup) · GitHub and comments within. Warning: It compiles,I really didn’t check anything else Let me know if this is useful to you.
I will want to do more thinking how to expose this in a clean way in CGE — this behavior makes some assumptions, e.g. you will need to sometimes call UpdateChildren
manually – if you add / scale the children at runtime. But I guess in your case it doesn’t matter if you use this for stuff like trees, but you probably don’t reposition at runtime.
This behavior also wastes opportunity to potentially reject whole groups that are outside of the distance. As it applies DistanceCulling
on each scene, each scene will be checked separately. But one can envision a useful optimization that groups TCastleTransforms, effectively creativing BVH from them, and can reject whole groups.
So… I should think how to do this in long-term in a way that I really like But for now, hopefully this will be useful to you as a “wrapper over DistanceCulling that makes it more comfortable”. It does make an improvement: you can manage a group of scenes with a single property (you add one instance of TDistanceCullingGroup
to a one TreeGroup
and you let it auto-configure culling on all children trees).
If this wasn’t explained by one of my statements above, please submit a testcase – I’ll be happy to investigate
Hi Michalis,
thank you very much for the explanation.
DistanceCulling is not a big problem, because I can check in the editor when zooming out and in.
The Problem with the weapon shadow, if I understand you right, is not possible on the child-scene.
So I created a new scene (SceneAvatarWeapon) which is not a child of the SceneAvatar.
In the Update method I implemented this:
if Scene1.Exists then
begin
Scene1.GetWorldView(aPos,aDir,aUp);
SceneAvatarWeapon.SetWorldView(aPos,aDir,aUp);
end;
if Scene4.Exists then
begin
Scene4.GetWorldView(aPos,aDir,aUp);
SceneAvatarWeapon.SetWorldView(aPos,aDir,aUp);
end;
I take the translation and direction from the unvisible child and use them for the visible weapon with shadow.
It seems to work. Maybe to much work around?
Regards
Didi
In case of this issue (scene1, scene4, weapon) — oh, I admittedly just don’t understand the issue. If you can send the testcase, I can judge better
The code you show is a valid code to synchronize the world transformation of 2 TCastleTransform
. It looks OK, but I don’t know the purpose of it. But this is indeed a valid way to avoid having child-parent relationship, and just “synchronize by hand” some transformations, if necessary for any reason.
CGE - examples - viewport_and_scenes - shadows
duplicate the Scene1 (now we have two soldiers with shadow)
Make the Scene5 to a child of Scene1 the shadow is gone.
Fixed!
I know, it’s been… a year since you have reported this. Sorry for such a long wait – but I finally got to this on my TODO! I will not win a medal for the fastest developer this way, but maybe I’ll get a medal for the most persistent one
Fixed in this commit: Fix shadow volumes casting when one TCastleScene is a child of another · castle-engine/castle-engine@0e1a9db · GitHub . As usual, the fix will be available in the engine you can download on Download | Castle Game Engine in a few hours, once it passes automatic tests. You can observe this page: Comparing snapshot...master · castle-engine/castle-engine · GitHub , when it will no longer show the commit “Fix shadow volumes casting when one TCastleScene is a child of another” then this commit is part of the release.
Thank you very much, this is so cool.
Now I have easy shadows on a character build in CGE as a TCastleTransform animated by code. I will try to do this as a behavior. This could be very interesting.