inconsistent (wrong) shadow rendering between structural meshes and func_* entities
Paril has already mentioned this but maybe more people have the problem ^^
Description:
When using structural meshes, shadows are rendered correctly. However, when using meshes defined as brush entities with the class func_detail_illusionary or func_illusionary_visblocker, the shadow rendering appears to produce incorrect results. This behavior does not occur with func_detail, where shadows are rendered as expected.
Steps to Reproduce:
Create a scene with the same mesh constellation used in three configurations:
- As a structural mesh
- As a func_detail entity (optional)
- As a func_detail_illusionary entity
- As a func_illusionary_visblocker entity
(It needs to be a mesh constellation like in the image.)
Observe the shadow behavior in each case.
Note that shadows render correctly for structural meshes and func_detail, but not for the other two entity types.
Expected Behavior: Shadows should be rendered consistently for all entity types, especially when their geometry is identical.
Used Version: ericw-tools-2.0.0-alpha9-win64
params:
-bounce -bouncescale 0.5
The difference is most likely coming from luxel placement. In the detail illusionary, and illusionary visblocker cases, we’re probably putting the luxels inside the central part of the grave (which casts shadows), leading to the unwanted shadow on the base. In the structural one, we do a point contents check and end up moving the luxel outside of the solid.
Agree it would be desirable if these were lit the same. I’ll have to think about what to do here
Would it be possible, during the compiling process (on the fly), to avoid assigning shadow rendering calculations to func_ entities entirely, and instead create a temporary copy of these entities (e.g. func_detail_illusionary or func_illusionary_visblocker) as structural meshes solely for performing a point contents check — and then "delete" them afterward?
Since shadows are statically baked, they wouldn’t be affected by the removal of the temporary geometry — or am I mistaken?
With the following custom entity, it handles the luxels correctly, but the shading is otherwise inconsistent:
void() func_fake_illusionary = {
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
setmodel(self, self.model);
};
func_fake_illusionary
(gravestone behind is brighter)
IMPORTANT: The ground must also be set to func_fake_illusionary. If needed, you can add a flag to make it solid.
Leaving the ground as structural will result in areas at the ground that are not properly shadowed.
structural
Okay, very interessing -> If I select all gravestones, including the ground, and convert them into a "single" func_fake_illusionary entity, I get the following result:
... looks like structural result
but why? ^^
With a custom bmodel like func_fake_illusionary, brushes are compiled as CONTENTS_SOLID and we do the “solid contents push luxels outside” behaviour that is giving you the desired lighting. Light/qbsp dont’t know what eventual collision settings it will have in game.
For func_detail_illusionary, we can’t use that directly (the “solid contents push luxels out” behaviour) because that breaks lighting inside the volume, by design. And the player camera is valid inside func_detail_illusionary.
possibly related:
from left to right,
- func_train
- func_train with _shadow 1 -> This one looks a bit off.
- func_group