Convert shader to linear color pipeline #44
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The uber-shader in
material.jsmixes gamma and linear color space operations throughout, causing incorrect brightness levels — particularly visible in envmap reflections where dark surfaces are too dim and bright surfaces blow out.Current state:
pow(light, 1/2.2)before multiplying with basepow(sample, 2.2), scaled, gamma-encoded withpow(result, 1/2.2)before addingThis piecemeal approach compounds gamma errors at each step.
Solution
Convert the entire shader to a linear pipeline:
Linearize all inputs at the start:
baseColor = pow(texture2D(baseTexture, vUv).rgb, vec3(2.2))(sRGB → linear)colorTint— linearize if stored in sRGBAll math in linear space:
Single gamma encode at final output:
gl_FragColor = vec4(pow(color, vec3(1.0/2.2)), alpha)Impact
This will affect every visual in the scene — lighting brightness, envmap reflections, fog blending, self-illumination, color tinting. Ground truth comparisons should be done carefully with pixel sampling.
Considerations
ENV_MAP_SCALEvalue may need adjustment once everything is in linear space.renderer.outputColorSpacesetting may interact with our manual gamma encode — need to ensure we're not double-encoding.Related
Implemented in
36368a2.All texture inputs (base, detail blend result, cubemap, reflection RT, vertex colors) are linearized at the start of the pipeline. All lighting and blending math happens in linear space. Single gamma encode at output (including water, modulate, and lightmapOnly early-return paths).
CPU-side linearization for static uniforms:
colorTint,selfIllumTint,entityColor, fog colors.envmapTintis intentionally NOT linearized — it was already applied in linear space in Source's pipeline (between cubemap linearization and re-gamma), so it's a linear multiplier.ENV_MAP_SCALE reduced from 2.0 to 1.0 for the linear pipeline. Detail blending stays in gamma space before linearization so Source-designed blend modes (mod2x neutral at 0.5, etc.) work correctly.