ericw-tools icon indicating copy to clipboard operation
ericw-tools copied to clipboard

inconsistent (wrong) shadow rendering between structural meshes and func_* entities

Open rnd332tec opened this issue 10 months ago • 6 comments

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.

Image

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

rnd332tec avatar Apr 30 '25 20:04 rnd332tec

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

ericwa avatar May 01 '25 00:05 ericwa

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?

rnd332tec avatar May 01 '25 08:05 rnd332tec

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) Image 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 Image

rnd332tec avatar May 01 '25 12:05 rnd332tec

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

Image

Image

but why? ^^

rnd332tec avatar May 01 '25 16:05 rnd332tec

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.

ericwa avatar May 02 '25 15:05 ericwa

possibly related:

Image

from left to right,

  • func_train
  • func_train with _shadow 1 -> This one looks a bit off.
  • func_group

ericwa avatar Aug 29 '25 04:08 ericwa