diff --git a/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js index 53c473b5ed0ade..31e2829f6d89c9 100644 --- a/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js @@ -4,6 +4,10 @@ vec4 LinearTransferOETF( in vec4 value ) { return value; } +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 ); +} + vec4 sRGBTransferOETF( in vec4 value ) { return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); } diff --git a/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js index 517d32ec6daa5c..76fa3e461bd9e4 100644 --- a/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js @@ -3,6 +3,14 @@ export default /* glsl */` vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv ); + #ifdef DECODE_VIDEO_TEXTURE_EMISSIVE + + // use inline sRGB decode until browsers properly support SRGB8_ALPHA8 with video textures (#26516) + + emissiveColor = sRGBTransferEOTF( emissiveColor ); + + #endif + totalEmissiveRadiance *= emissiveColor.rgb; #endif diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js index c162b47c29a38d..7ed5866818478c 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js @@ -7,8 +7,8 @@ export default /* glsl */` // use inline sRGB decode until browsers properly support SRGB8_ALPHA8 with video textures (#26516) - sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w ); - + sampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor ); + #endif diffuseColor *= sampledDiffuseColor; diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index dbefaf90f330ad..f53af2d422d410 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -816,6 +816,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', + parameters.decodeVideoTextureEmissive ? '#define DECODE_VIDEO_TEXTURE_EMISSIVE' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.reverseDepthBuffer ? '#define USE_REVERSEDEPTHBUF' : '', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index dde9db098c9cae..4ef67b8e02c21a 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -341,6 +341,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities toneMapping: toneMapping, decodeVideoTexture: HAS_MAP && ( material.map.isVideoTexture === true ) && ( ColorManagement.getTransfer( material.map.colorSpace ) === SRGBTransfer ), + decodeVideoTextureEmissive: HAS_EMISSIVEMAP && ( material.emissiveMap.isVideoTexture === true ) && ( ColorManagement.getTransfer( material.emissiveMap.colorSpace ) === SRGBTransfer ), premultipliedAlpha: material.premultipliedAlpha, @@ -558,8 +559,10 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities _programLayers.enable( 18 ); if ( parameters.decodeVideoTexture ) _programLayers.enable( 19 ); - if ( parameters.alphaToCoverage ) + if ( parameters.decodeVideoTextureEmissive ) _programLayers.enable( 20 ); + if ( parameters.alphaToCoverage ) + _programLayers.enable( 21 ); array.push( _programLayers.mask );