feat(d3d): add opt-in per-pixel lighting and smooth normals

Merged
NO
10d ago
+525-7

Stacked on #122. Review and merge after it.

Summary

Two opt-in D3D11 shading options for the game's fixed-function lighting:

RECOMP_D3D_PIXEL_LIGHTING=1   evaluate the game's directional and point lights per pixel instead of per vertex
RECOMP_D3D_SMOOTH_NORMALS=1   rebuild normals welded across split vertices (flat weld grid, cached per draw)
RECOMP_PERF_COUNTER=1         adds smooth_hits / misses / rebuild_ms to the performance line

Both are off by default; the default shading path is unchanged. See docs/building.md.

Verification

  • MSVC Debug build and ctest at this layer: 38/38 passed.
  • python tools/public_export.py verify --require-public-tree passes.
  • clang, macOS and Linux: covered by this PR's public-ci run.
  • Player play test of the integrated build: lighting renders correctly with both options on; the difference from per-vertex lighting is subtle on most stages.

Merge danger

Two-way door. Opt-in only; it touches the D3D11 presenter shader and the sun shadow header's shader anchors.

Contribution checklist

  • The change follows AGENTS.md and CONTRIBUTING.md.
  • No XBE, generated game C, retail instruction bytes, extracted assets or
    filenames, saves, BIOS data, private paths, or run evidence are included.
  • Third-party material and its license are identified, if applicable.