Skip to content

Commit

Permalink
Add s rgb to linear with shader (#142)
Browse files Browse the repository at this point in the history
* add sRGBToLinearWithShader to Texture

* add space after !

* fix test of webgl_srgb_textures
  • Loading branch information
nianxy authored Nov 27, 2023
1 parent b0715d5 commit 3c76e11
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 12 deletions.
9 changes: 5 additions & 4 deletions examples/webgl_srgb_textures.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

import * as THREE from '@oppentech/three';

let camera, scene, renderer1, renderer2;
let camera, scene, renderer1, renderer2, texture;

init();

Expand All @@ -52,8 +52,9 @@
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

new THREE.TextureLoader().load('textures/checkboard.png', ( texture ) => {
new THREE.TextureLoader().load('textures/checkboard.png', ( tex ) => {

texture = tex;
texture.encoding = THREE.sRGBEncoding;
material.map = texture;
animate();
Expand All @@ -80,10 +81,10 @@

requestAnimationFrame( animate );

THREE.Texture.useSrgbTextures = true;
texture.sRGBToLinearWithShader = false;
renderer1.render( scene, camera );

THREE.Texture.useSrgbTextures = false;
texture.sRGBToLinearWithShader = true;
renderer2.render( scene, camera );

}
Expand Down
2 changes: 1 addition & 1 deletion src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ function WebGLRenderer( parameters = {} ) {

}

if ( capabilities.isWebGL2 && Texture.useSrgbTextures && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding ) {
if ( capabilities.isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding && ! map.sRGBToLinearWithShader ) {

encoding = LinearEncoding; // disable inline decode for sRGB textures in WebGL 2

Expand Down
14 changes: 7 additions & 7 deletions src/renderers/webgl/WebGLTextures.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

}

function getInternalFormat( internalFormatName, glFormat, glType, encoding ) {
function getInternalFormat( internalFormatName, glFormat, glType, encoding, sRGBToLinearWithShader = ! Texture.useSrgbTextures ) {

if ( isWebGL2 === false ) return glFormat;

Expand Down Expand Up @@ -165,7 +165,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( isWebGL2 && Texture.useSrgbTextures && encoding === sRGBEncoding ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( isWebGL2 && encoding === sRGBEncoding && ! sRGBToLinearWithShader ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
if ( glType === _gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = _gl.RGBA4;
if ( glType === _gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = _gl.RGB5_A1;

Expand Down Expand Up @@ -562,7 +562,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
glFormat = utils.convert( texture.format, texture.encoding );

let glType = utils.convert( texture.type ),
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.sRGBToLinearWithShader );

setTextureParameters( textureType, texture, supportsMips );

Expand Down Expand Up @@ -921,7 +921,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
supportsMips = isPowerOfTwo( image ) || isWebGL2,
glFormat = utils.convert( texture.format, texture.encoding ),
glType = utils.convert( texture.type ),
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.sRGBToLinearWithShader );

const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );
const allocateMemory = ( textureProperties.__version === undefined );
Expand Down Expand Up @@ -1086,7 +1086,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

const glFormat = utils.convert( texture.format, texture.encoding );
const glType = utils.convert( texture.type );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.sRGBToLinearWithShader );
const renderTargetProperties = properties.get( renderTarget );

if ( ! renderTargetProperties.__hasExternalTextures ) {
Expand Down Expand Up @@ -1194,7 +1194,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

const glFormat = utils.convert( texture.format, texture.encoding );
const glType = utils.convert( texture.type );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.sRGBToLinearWithShader );
const samples = getRenderTargetSamples( renderTarget );

if ( isMultisample && renderTarget.useRenderbuffer ) {
Expand Down Expand Up @@ -1419,7 +1419,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

const glFormat = utils.convert( texture.format, texture.encoding );
const glType = utils.convert( texture.type );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.sRGBToLinearWithShader );
const samples = getRenderTargetSamples( renderTarget );
_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );

Expand Down
5 changes: 5 additions & 0 deletions src/textures/Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class Texture extends EventDispatcher {
this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not
this.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)

// In WebGL2, sRGB textures can be trancoded to Linear automatically, but reference to this issue: https://github.com/mrdoob/three.js/issues/26183
// there're performance issues when doing this, so you can set the sRGBToLinearWithShader to false to transcode the sRGB texture to Linear with
// shader, especially to those textures that are updated in each frame
this.sRGBToLinearWithShader = ! Texture.useSrgbTextures;

}

updateMatrix() {
Expand Down

0 comments on commit 3c76e11

Please sign in to comment.