Skip to content

Commit

Permalink
WebGLRenderer: Remove inline sRGB decode. (mrdoob#23129)
Browse files Browse the repository at this point in the history
* WebGLRenderer: Remove inline sRGB decode.

* Update WebGLTextures.js

* VideoTexture: Use inline sRGB decode.

* WebGLTexture: Fix video textures with WebGL 1.
  • Loading branch information
Mugen87 authored Jan 4, 2022
1 parent 5655fbe commit 05fc79c
Show file tree
Hide file tree
Showing 26 changed files with 208 additions and 214 deletions.
1 change: 0 additions & 1 deletion examples/jsm/loaders/GLTFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,6 @@ class GLTFMeshStandardSGMaterial extends MeshStandardMaterial {
'vec3 specularFactor = specular;',
'#ifdef USE_SPECULARMAP',
' vec4 texelSpecular = texture2D( specularMap, vUv );',
' texelSpecular = sRGBToLinear( texelSpecular );',
' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',
' specularFactor *= texelSpecular.rgb;',
'#endif'
Expand Down
17 changes: 4 additions & 13 deletions examples/jsm/nodes/utils/ColorSpaceNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ class ColorSpaceNode extends TempNode {

}

fromDecoding( encoding ) {
fromDecoding() {

const components = ColorSpaceNode.getEncodingComponents( encoding );
// TODO: Remove fromDecoding()

const components = ColorSpaceNode.getEncodingComponents( LinearEncoding );

this.method = components[ 0 ] + 'ToLinear';
this.factor = components[ 1 ];
Expand Down Expand Up @@ -106,14 +108,6 @@ ColorSpaceNode.Nodes = ( function () {
}`
);

const sRGBToLinear = new FunctionNode( /* glsl */`
vec4 sRGBToLinear( 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.w );
}`
);

const LinearTosRGB = new FunctionNode( /* glsl */`
vec4 LinearTosRGB( in vec4 value ) {
Expand All @@ -124,15 +118,12 @@ ColorSpaceNode.Nodes = ( function () {

return {
LinearToLinear: LinearToLinear,
sRGBToLinear: sRGBToLinear,
LinearTosRGB: LinearTosRGB
};

} )();

ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear';

ColorSpaceNode.SRGB_TO_LINEAR = 'sRGBToLinear';
ColorSpaceNode.LINEAR_TO_SRGB = 'LinearTosRGB';

ColorSpaceNode.getEncodingComponents = function ( encoding ) {
Expand Down
27 changes: 5 additions & 22 deletions examples/jsm/renderers/nodes/display/ColorSpaceNode.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import TempNode from '../core/Node.js';
import { ShaderNode,
vec3,
pow, mul, add, sub, mix, join,
pow, mul, sub, mix, join,
lessThanEqual } from '../ShaderNode.js';

import { LinearEncoding, sRGBEncoding } from '../../../../../build/three.module.js';
Expand All @@ -12,22 +12,6 @@ export const LinearToLinear = new ShaderNode( ( inputs ) => {

} );

export const sRGBToLinear = new ShaderNode( ( inputs ) => {

const { value } = inputs;

const rgb = value.rgb;

const a = pow( add( mul( rgb, 0.9478672986 ), vec3( 0.0521327014 ) ), vec3( 2.4 ) );
const b = mul( rgb, 0.0773993808 );
const factor = vec3( lessThanEqual( rgb, vec3( 0.04045 ) ) );

const rgbResult = mix( a, b, factor );

return join( rgbResult.r, rgbResult.g, rgbResult.b, value.a );

} );

export const LinearTosRGB = new ShaderNode( ( inputs ) => {

const { value } = inputs;
Expand All @@ -46,7 +30,6 @@ export const LinearTosRGB = new ShaderNode( ( inputs ) => {

const EncodingLib = {
LinearToLinear,
sRGBToLinear,
LinearTosRGB
};

Expand All @@ -66,8 +49,6 @@ function getEncodingComponents( encoding ) {
class ColorSpaceNode extends TempNode {

static LINEAR_TO_LINEAR = 'LinearToLinear';

static SRGB_TO_LINEAR = 'sRGBToLinear';
static LINEAR_TO_SRGB = 'LinearTosRGB';

constructor( method, node ) {
Expand All @@ -92,9 +73,11 @@ class ColorSpaceNode extends TempNode {

}

fromDecoding( encoding ) {
fromDecoding() {

const components = getEncodingComponents( encoding );
// TODO: Remove fromDecoding()

const components = getEncodingComponents( LinearEncoding );

this.method = components[ 0 ] + 'ToLinear';
this.factor = components[ 1 ];
Expand Down
2 changes: 0 additions & 2 deletions examples/jsm/utils/RoughnessMipmapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ function _getMipmapMaterial() {
#define ENVMAP_TYPE_CUBE_UV
vec4 envMapTexelToLinear( vec4 a ) { return a; }
#include <cube_uv_reflection_fragment>
float roughnessToVariance( float roughness ) {
Expand Down
1 change: 0 additions & 1 deletion examples/webgl_lightprobe_cubecamera.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
camera.position.set( 0, 0, 30 );

const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, {
encoding: THREE.sRGBEncoding, // since gamma is applied during rendering, the cubeCamera renderTarget texture encoding must be sRGBEncoding
format: THREE.RGBAFormat
} );

Expand Down
19 changes: 10 additions & 9 deletions examples/webgl_materials_nodes.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
const library = {};
let serialized = false;
const textures = {
brick: { url: 'textures/brick_diffuse.jpg' },
grass: { url: 'textures/terrain/grasslight-big.jpg' },
grassNormal: { url: 'textures/terrain/grasslight-big-nm.jpg' },
decalDiffuse: { url: 'textures/decal/decal-diffuse.png' },
decalNormal: { url: 'textures/decal/decal-normal.jpg' },
cloud: { url: 'textures/lava/cloud.png' },
spherical: { url: 'textures/envmap.png' }
brick: { url: 'textures/brick_diffuse.jpg', encoding: THREE.sRGBEncoding },
grass: { url: 'textures/terrain/grasslight-big.jpg', encoding: THREE.sRGBEncoding },
grassNormal: { url: 'textures/terrain/grasslight-big-nm.jpg', encoding: THREE.LinearEncoding },
decalDiffuse: { url: 'textures/decal/decal-diffuse.png', encoding: THREE.sRGBEncoding },
decalNormal: { url: 'textures/decal/decal-normal.jpg', encoding: THREE.LinearEncoding },
cloud: { url: 'textures/lava/cloud.png', encoding: THREE.sRGBEncoding },
spherical: { url: 'textures/envmap.png', encoding: THREE.sRGBEncoding }
};

const param = { example: new URL( window.location.href ).searchParams.get( 'e' ) || 'mesh-standard' };
Expand All @@ -59,6 +59,7 @@

texture = textures[ name ].texture = new THREE.TextureLoader().load( textures[ name ].url );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.encoding = textures[ name ].encoding;

library[ texture.uuid ] = texture;

Expand Down Expand Up @@ -187,7 +188,7 @@
'basic / spherical-reflection': 'spherical-reflection',
'basic / standard': 'standard',
'basic / uv-transform': 'uv-transform',

'adv / bias': 'bias',
'adv / camera-depth': 'camera-depth',
'adv / caustic': 'caustic',
Expand Down Expand Up @@ -215,7 +216,7 @@
'node / normal': 'node-normal',
'node / position': 'node-position',
'node / reflect': 'node-reflect',

'misc / basic-material': 'basic-material',
'misc / custom-attribute': 'custom-attribute',
'misc / firefly': 'firefly',
Expand Down
3 changes: 3 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,6 @@ export const StreamCopyUsage = 35042;

export const GLSL1 = '100';
export const GLSL3 = '300 es';

export const _SRGBFormat = 1034; // fallback for WebGL 1
export const _SRGBAFormat = 1035; // fallback for WebGL 1
63 changes: 63 additions & 0 deletions src/extras/ImageUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createElementNS } from '../utils.js';
import { SRGBToLinear } from '../math/Color.js';

let _canvas;

Expand Down Expand Up @@ -61,6 +62,68 @@ class ImageUtils {

}

static sRGBToLinear( image ) {

if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {

const canvas = createElementNS( 'canvas' );

canvas.width = image.width;
canvas.height = image.height;

const context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0, image.width, image.height );

const imageData = context.getImageData( 0, 0, image.width, image.height );
const data = imageData.data;

for ( let i = 0; i < data.length; i ++ ) {

data[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255;

}

context.putImageData( imageData, 0, 0 );

return canvas;

} else if ( image.data ) {

const data = image.data.slice( 0 );

for ( let i = 0; i < data.length; i ++ ) {

if ( data instanceof Uint8Array || data instanceof Uint8ClampedArray ) {

data[ i ] = Math.floor( SRGBToLinear( data[ i ] / 255 ) * 255 );

} else {

// assuming float

data[ i ] = SRGBToLinear( data[ i ] );

}

}

return {
data: data,
width: image.width,
height: image.height
};

} else {

console.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' );
return image;

}

}

}

export { ImageUtils };
Loading

0 comments on commit 05fc79c

Please sign in to comment.