Skip to content

fix(shadows): fix fog of war, black infantry, and building shadows#165

Merged
fbraz3 merged 14 commits into
mainfrom
issue-88-fog-of-war-terrain
Jun 18, 2026
Merged

fix(shadows): fix fog of war, black infantry, and building shadows#165
fbraz3 merged 14 commits into
mainfrom
issue-88-fog-of-war-terrain

Conversation

@fbraz3

@fbraz3 fbraz3 commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Description

This PR addresses visual issues with terrain Fog of War, infantry rendering, and building shadows in the base game on macOS/Vulkan.

Closes #88

Changes

  • Fog of War: Backported Zero Hour's static map-wide shroud texture behavior in W3DShroud.cpp to prevent texture coordinate coordinate out-of-bounds under Vulkan/DXVK.
  • Skinned Mesh Vertex Diffuse Color: Default to 0xFFFFFFFF (white) when mesh diffuse color is null, resolving GLA Worker pitch-black torso rendering.
  • Volumetric Shadow SKIN Guard: Return FALSE in initFromMesh and initFromHLOD for skinned meshes so they do not enter CPU volumetric stencil shadow generation and corrupt the stencil pipeline.
  • Infantry Light Clamping: Clamped scaled ambient and diffuse infantry light colors to (1.0f, 1.0f, 1.0f) using Vector3::Cap_Absolute_To in W3DScene.cpp to prevent Vulkan/DXVK shader overflows.
  • Decal Batch Loop Fixes: Initialized batch state with processed shadow's texture and type instead of the list heads in W3DProjectedShadow.cpp.
  • Dynamic Projected Shadows: Set SHADOW_DYNAMIC_PROJECTION flags on animated shadow casters.
  • Decal Mask Support: Supported SHADOW_ALPHA_DECAL and SHADOW_ADDITIVE_DECAL as valid decal shadows inside addShadow.

fbraz3 added 14 commits June 16, 2026 22:24
Backport Zero Hour's static map-wide shroud texture behavior to the
Generals base game. This prevents DXVK dynamic offset matrix sampling
out-of-bounds under Vulkan/MoltenVK.

Also make SDL3GameEngine audio inclusions mutually exclusive to avoid
type redefinition conflicts when both OpenAL and MiniAudio options are
present in the cache.

Fixes #88
Resolve redefinition conflicts in FFmpegVideoPlayer when both SAGE_USE_MINIAUDIO and SAGE_USE_OPENAL are defined in the CMake cache. This ensures the primary MiniAudio backend takes precedence.
Backport Zero Hour check to W3DVolumetricShadow::initFromHLOD to skip volumetric shadow generation for skin meshes. Infantries are skin meshes, and generating stencil shadow volumes on the CPU for animated skeletal models is incorrect and causes infantry to render as solid black silhouettes under MoltenVK/DXVK.
Skeletal animated hierarchies (like infantry) cannot accurately project
CPU shadow volumes. In the base game under MoltenVK/Vulkan/DXVK, attempting
to cast volumetric shadows on bone-attached rigid sub-meshes of a skinned
model (like the GLA Worker's torso/vest) leaves the stencil/GPU state broken,
rendering them as solid black silhouettes.

Checking the entire HLOD for skinned meshes and skipping volumetric shadow
geometry generation for the whole hierarchy resolves this rendering bug,
allowing them to fallback to projected/decal shadows exactly as in Zero Hour.

Fixes #88
TheDisplay->step() and TheDisplay->draw() were being called
redundantly in GameEngine::execute() in addition to the call
already dispatched via TheGameClient->update(). This caused a
double-presentation per frame loop iteration, resulting in:
- Incorrect FPS calculations (e.g. 170 FPS on 170Hz monitor)
- Game logic and animations running at twice normal speed

Removing the extra draw call aligns the base game main loop with
Zero Hour (GeneralsMD), which did not have this duplicate call.
Correct 30 FPS cap and game speed are now restored.

// GeneralsX @BugFix MrMeeseeks 17/06/2026
…in initFromMesh

initFromHLOD already skipped skinned sub-meshes (CNC3/gth
comment at line 651). initFromMesh had no equivalent guard,
meaning a standalone MeshClass with the SKIN flag could still
enter the CPU shadow volume pipeline, potentially corrupting
the stencil state under DXVK/Vulkan.

Add SKIN flag check to initFromMesh, mirroring the existing
HLOD behavior, matching the fix already applied to the Generals
base game in W3DVolumetricShadow.cpp.

// GeneralsX @BugFix Mr. Meeseeks 17/06/2026
- Record ZH initFromMesh SKIN guard fix in 2026-06-DIARY.md
- Document diffuse=0 audit findings (BaseHeightMap is intentional)
- Update INFANTRY_SHADOW_FIX_SUMMARY.md with completed follow-up actions,
  current clean state, and updated smoke test checklist
… bug in W3DProjectedShadow.cpp causing black square building shadows and black infantry in Generals base game.
The building shadow alpha decal combined with the SHADOW_DECAL flag produced bitmask values (e.g. 0x21) that failed exact enum switch/equality matching in flushDecals, updateShadowNumbers, renderShadows, and updateTexture.

Replace exact equality checks with bitwise AND checks to correctly route and render alpha-blended/additive-blended decals and projection updates.
- Clamps scaled ambient and diffuse colors for infantry to 1.0f in W3DScene.cpp
- Fixes initialization of lastShadowDecalTexture and lastShadowType in W3DProjectedShadow.cpp loops
- Flag animated caster shadows as dynamic projected shadows in addShadow
- Support SHADOW_ALPHA_DECAL and SHADOW_ADDITIVE_DECAL type checks in addShadow

Closes #88
@fbraz3 fbraz3 merged commit 91d8e27 into main Jun 18, 2026
8 checks passed
@fbraz3 fbraz3 deleted the issue-88-fog-of-war-terrain branch June 18, 2026 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Visual bug

1 participant