fix(web): decode textures as sRGB in 3D viewers

TextureLoader leaves colorSpace as NoColorSpace, so card, tile, token, model, and part art is uploaded as linear and then double-decoded in the shader, washing out contrast. Mark each texture sRGB so the GPU decodes it once, correctly.
This commit is contained in:
2026-08-15 12:25:21 +08:00
parent fc9f756d52
commit 3dd3db5643
5 changed files with 29 additions and 0 deletions
+7
View File
@@ -86,6 +86,13 @@ export function PartMesh({ part, baseUrl }: { part: Part; baseUrl?: string }) {
const face = useTexture(faceUrl ? assetUrl(faceUrl) : FALLBACK_URL);
const back = useTexture(backUrl ? assetUrl(backUrl) : FALLBACK_URL);
// Part art is sRGB-encoded; `TextureLoader` leaves `colorSpace` as
// `NoColorSpace`, which double-decodes it in the shader and washes out
// contrast. Mark it sRGB so the GPU decodes it once, correctly. The sprite
// clones below inherit this from the source.
face.colorSpace = THREE.SRGBColorSpace;
back.colorSpace = THREE.SRGBColorSpace;
const trace = useTrace(shapeUrl, traceImage);
const { frontGeo, backGeo, wallsGeo } = useMemo(() => {