From 24e65b29095b803d47c8f117b7436f48bca9da32 Mon Sep 17 00:00:00 2001 From: AlaricBaraou Date: Wed, 10 Sep 2025 18:42:35 +0900 Subject: [PATCH] fix(BatchedText): Correct color rendering with Three.js Color Management --- packages/troika-three-text/src/BatchedText.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/troika-three-text/src/BatchedText.js b/packages/troika-three-text/src/BatchedText.js index 19e86411..f81c90f2 100644 --- a/packages/troika-three-text/src/BatchedText.js +++ b/packages/troika-three-text/src/BatchedText.js @@ -1,5 +1,5 @@ import { Text } from "./Text.js"; -import { DataTexture, FloatType, RGBAFormat, Vector2, Box3, Color, DynamicDrawUsage } from "three"; +import { ColorManagement, DataTexture, FloatType, RGBAFormat, Vector2, Box3, Color, DynamicDrawUsage } from "three"; import { glyphBoundsAttrName, glyphIndexAttrName } from "./GlyphsGeometry.js"; import { createDerivedMaterial } from "troika-three-utils"; import { createTextDerivedMaterial } from "./TextDerivedMaterial.js"; @@ -425,8 +425,14 @@ function createBatchedTextMaterial (baseMaterial) { // language=GLSL vertexDefs: ` uniform bool uTroikaIsOutline; + // sRGB->Linear conversion function, from Three.js https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js + vec4 sRGBTransferEOTF( in vec4 value ) { + return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); + } vec3 troikaFloatToColor(float v) { - return mod(floor(vec3(v / 65536.0, v / 256.0, v)), 256.0) / 256.0; + vec3 srgbColor = mod(floor(vec3(v / 65536.0, v / 256.0, v)), 256.0) / 255.0; + + return ${ColorManagement.enabled ? 'sRGBTransferEOTF(vec4(srgbColor, 1.0)).rgb' : 'srgbColor'}; } `, // language=GLSL prefix="void main() {" suffix="}"