Add spatial irradiance and character lighting adapter

This commit is contained in:
chazmm committed 2026-09-08 16:41:42 +01:00
1 parent 8c31384a12
commit 7d44d84f19
15 files changed
+730 -5

No files matched your search

+66 -2
View File
@@ -1,6 +1,6 @@
# Character lighting investigation
Status: native character-lighting reconstruction started; no runtime lighting change yet.
Status: position-dependent character lighting implemented; user-run visual validation pending.
Observed in the local reference renderer (`skate3_native_scene.cpp`, CaptureCharLighting,
and `scene_char.hlsli`): defaultcharacter/CAC shading consumes a directional key,
@@ -24,7 +24,7 @@ Observed in TU3 generated PPC source:
ambient, and arrays of cSimpleLightData. Do not assume these are the same as
the spatial baked SH samples just because of the class name.
Implementation work still required:
Initial investigation checklist (superseded by the implementation status below):
1. Recover the spatial irradiance resource/registration and sampling path and
resolve default probe selection from world/render state.
2. Extract character frame inputs and per-material parameters through native
@@ -41,3 +41,67 @@ Implementation work still required:
Reference caveat: community symbol labels are hypotheses. In particular the
82E3B548 label must not be treated as a verified prototype. No copied renderer
capture's lighting constants should become a universal outdoor preset.
## Implementation, 2026-09-08
`tools.asset_pipeline.irradiance` extracts RX2 type `0xEB0024` from the district's
other presentation assets. Its section starts with count and relative array
offset; each 160-byte record contains nine float4 SH rows, XYZ at byte 144 and a
runtime link word at 156. The `SHP1` sidecar preserves groups, values and original
world coordinates, converting only endianness. University contains 17,493 samples
in 64 resources. Future map conversions write `<map>.irradiance` beside the map.
TU3 `0x827E6E28` registers these resources into a 41-by-41 spatial grid;
`0x827E6AC8` selects the nearest sample in three dimensions from the XZ
neighborhood and falls back to the default coefficients. `0x827E7348` checks a
six-entry MRU cache with a strict squared-distance threshold of 6.25. Raw binary
constant `0x820BD16C` is 15.0 (query margin); `0x822F8F38` is 6.25. The evidence
is the generated PPC instructions corroborated with resource contents and the
TU3 dump with SHA-256
`F4AA113EB541BFBA03DBC108CF5AB43F58C965B20FA3B82F9C40938A0AD841C4`.
Addresses use the dump's `0x82000000` base.
`retail_irradiance.rs` retains the native nearest-sample/cache behavior. Its
static-world adaptation searches all loaded groups using expanded bounds and an
XZ 15-metre neighborhood. It does not reproduce the original 12-resource
streaming limit or grid-cell boundary quantization. The freeskate collection
supplies the nine fallback rows; live changes of the manager's default mode are
not implemented. This is not trilinear probe interpolation.
`tools.asset_pipeline.character_lighting` resolves each selected model's
AttribulatorMaterialName through VLT inheritance and exports its nine complete
material parameter rows. Skin/face specular textures preserve the original red
channel separately; the GLB's grayscale inverse-roughness conversion is not used
as the native specular mask. Source assets remain private.
`retail_character.rs` replaces the ten named retail GLB materials while retaining
Bevy's skinned vertex path. It updates the SH rows from PlayerRoot's position.
The fragment shader evaluates the native SH basis, authored directional key,
ambient multiplier, rim response, key/rim highlights, normal maps and material
multiplier. Diffuse sampling accounts for the GLB's sRGB texture format before
the retail gamma-two decode. Output remains linear HDR for the existing shared
tone pass. The separate depth shader retains alpha rejection.
A zero-lux directional shadow source provides world/self occlusion to the
character's key and key specular terms. The baked world shader does not sample
this shadow map; remaining StandardMaterials receive zero additive sunlight.
This uses Bevy cascades/filtering/biases, not the console's exact cascade layout
and 9-tap shadow filter. It does not add a skater-shadow receiver to baked world
surfaces. No gameplay or physics code changes are involved.
Hair now uses the native wrapped diffuse/ambient/fresnel response, with the
authored material colours and the existing GLB dye/coverage composition. The
live CAC colour-register derivation and separate second-UV blended strand pass
are not reconstructed; hair keeps the installed cutout mode. This is an explicit
adapter limitation, not a claim of exact hair parity.
Scene exposure remains the existing 2.5 day-capture value shared with the world;
the regional exposure controller, water and fog are still unfinished. Missing
lighting sidecars leave the existing GLB material path active and log the reason.
Validation: 13 synthetic Python extraction/inheritance/GUID tests, two spatial
selection/cache tests, and the windowless world-render adapter test pass. Character
colour, shadow and normal-depth shader variants pass offline Naga composition
against the vendored Bevy 0.18 shader modules. Release compilation passes. The
game/recomp was not launched. User visual checks should cover exposed terrain,
sheltered spots, skin/clothing highlights, hair coverage and body/board shadows.
+6 -3
View File
@@ -99,8 +99,11 @@ the CPU transformation to native frame rows is not yet proven, so shader fog
remains disabled. The selected `material_fog/default` must not be confused
with the different `fog_default` collection.
Native water, character shaders, SSAO, SSR, bloom and volumetric lighting are
not yet ported. The water arrays are recoverable now, but flowing-water
Native water, SSAO, SSR, bloom and volumetric lighting are
not yet ported. Character lighting now has a dedicated adapter; see
[character-lighting-investigation.md](character-lighting-investigation.md) for
implemented terms, spatial data, validation and remaining parity differences.
The water arrays are recoverable now, but flowing-water
normal/tangent unpacking, ocean PCA input bindings and the separate horizon
water resource still need their own adapters. Character parity needs the
native CAC-composed texture/mask inputs plus verified key/rim/specular and
@@ -108,7 +111,7 @@ nine SH rows; portable GLB materials do not retain that contract. Reference
post effects need their depth/normal/reflection inputs and native pass ordering;
volumetric sun visibility also conflicts with the currently disabled world
sun-shadow source. These gaps are not enabled using guessed settings.
The character and
Characters without the new lighting sidecars and
unsupported world families still use Bevy materials beneath the shared tone
curve. Reflection normals use the reference's analytic world-up construction;
there has been no matched-camera pixel comparison against the recomp.