# Remaining gray-car brightness after r331 (r332)

The corrected r331 packaged capture is gray rather than the previous nearly
white result. Its rear bumper crop averages `(150.84,159.30,169.27)`, compared
with `(210.87,216.42,222.89)` before the transfer-function correction. The
remaining lift above the chosen `#858c94` is attributable to explicit preview
lighting and coat contributions. No additional renderer correction follows
from these measurements.

## Controlled shader contribution captures

These diagnostics use temporary Chrome `shaderSource` instrumentation at page
startup; they do not change the repository shader. Each capture loads the same
packaged Route 450 / distance 550 / radius 120 / 240SX pose and 1280×720 view.
Each reached `City scene ready` with 22,508 triangles, 128 textures, an empty
page error readout, and a ready reflection cube at the same world origin.
Traffic continued independently between captures. The sampled bumper rectangle
is x549–687, y433–460 (3,726 pixels).

| Diagnostic | Bumper mean RGB | Single interior pixel (610,445) |
| --- | --- | --- |
| [r331 full shader](../webgl-city/review/images/474-r331-player-color-after.png) | (150.84,159.30,169.27) | (180,192,205) |
| [Selected pigment only](../webgl-city/review/images/r332-pigment-only.png) | (132.71,139.70,147.68) | (133,140,148) |
| [Without main coat branch](../webgl-city/review/images/r332-no-coat.png) | (144.19,151.64,160.67) | (153,161,171) |
| [Without local diffuse pass on vehicles](../webgl-city/review/images/r332-no-local-lights.png) | (142.58,150.71,159.84) | (172,183,195) |
| [Without camera-relative diffuse multiplier](../webgl-city/review/images/r332-no-camera-diffuse.png) | (148.88,157.25,167.06) | (173,184,197) |

The pigment-only diagnostic returns the base-color uniform through the normal
sRGB display transfer before lighting/coat. Its interior pixel is exactly
`#858c94`; the rectangle mean includes seams and other edge pixels. This
confirms the input color reaches the display unchanged when lighting is
withheld. None of the diagnostics clips a bumper channel to 254 or above.
The isolated removals are not additive because the shader multiplies lighting
before adding the coat. The no-coat diagnostic suppresses the main paint
branch, retaining the separately applied lamp-specular branch.

## Code and asset trace

`drawPlayerCar` substitutes `playerPaintRgb()` for every unresolved paint
batch, so the GLB's `[0.52,0.55,0.58]` fallback is not the active player's
paint uniform. Runtime diagnostics report the decoded linear value
`(0.23455058,0.26225066,0.29613827)`, finish mode 2, and no base texture on
these batches. There is therefore no missing bound body texture whitening
this selected gray in the current draw.

The shader then multiplies by local scene illumination and by
`0.78 + diffuse*0.38`; it adds the environment and analytic coat terms.
These are existing viewer approximations. The main coat suppression lowers
the highlight pixel by 27/31/34 display codes, while removing local diffuse
lowers it by 8/9/10. This explains why individual panels can still appear
paler than the chosen swatch, especially against the darker roadway. It does
not establish that any particular coefficient should be reduced.

The recovered retail programmable shader instead uses per-vertex harmonic
lighting and named diffuse/specular/environment ranges, followed by the
recovered base-plus-environment equation. The live selected paint state,
technique, 40 `HarmonicCoeff` values, and actual diffuse/cube bindings remain
unavailable. A faithful replacement requires those inputs, as detailed in
[the shader recovery](car-programmable-shaders-r267.md) and
[the harmonic producer trace](car-harmonic-producer-r267.md). The static paint
resource name or a new guessed body texture cannot supply them.

## Source and packaged result

No renderer, exporter, material, lighting coefficient, opacity, or transform
was changed in r332. Source and packaged `viewer.js` remain byte-identical at
the r331 implementation. This note and the four diagnostic screenshots are
present in both source and dist. They identify the remaining approximation
without claiming a retail pixel match.
