Skip to content

Commit cba9457

Browse files
authoredSep 20, 2021
WebGLRenderer: Make use of SRGB8_ALPHA8. (mrdoob#22551)
* WebGLRenderer: Make use of SRGB8_ALPHA8. * Update screenshots. * Updated builds. * Revert "Update screenshots." This reverts commit 9f7c6cb. * Update screenshots. * Examples: Let SSRPass and SSRrPass work in linear space. * Examples: Clean up. * PMREMGenerator: Avoid inline decode/encode when using SRGB8_ALPHA8. * Updated builds. * Update screenshots. * Revert "Updated builds." This reverts commit 0fd81f8. * Revert "Updated builds." This reverts commit 447e88a.
1 parent c789b20 commit cba9457

16 files changed

+46
-55
lines changed
 

‎examples/jsm/loaders/GLTFLoader.js

-21
Original file line numberDiff line numberDiff line change
@@ -2761,31 +2761,13 @@ class GLTFParser {
27612761

27622762
let sourceURI = source.uri || '';
27632763
let isObjectURL = false;
2764-
let hasAlpha = true;
2765-
2766-
const isJPEG = sourceURI.search( /\.jpe?g($|\?)/i ) > 0 || sourceURI.search( /^data\:image\/jpeg/ ) === 0;
2767-
2768-
if ( source.mimeType === 'image/jpeg' || isJPEG ) hasAlpha = false;
27692764

27702765
if ( source.bufferView !== undefined ) {
27712766

27722767
// Load binary image data from bufferView, if provided.
27732768

27742769
sourceURI = parser.getDependency( 'bufferView', source.bufferView ).then( function ( bufferView ) {
27752770

2776-
if ( source.mimeType === 'image/png' ) {
2777-
2778-
// Inspect the PNG 'IHDR' chunk to determine whether the image could have an
2779-
// alpha channel. This check is conservative — the image could have an alpha
2780-
// channel with all values == 1, and the indexed type (colorType == 3) only
2781-
// sometimes contains alpha.
2782-
//
2783-
// https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
2784-
const colorType = new DataView( bufferView, 25, 1 ).getUint8( 0, false );
2785-
hasAlpha = colorType === 6 || colorType === 4 || colorType === 3;
2786-
2787-
}
2788-
27892771
isObjectURL = true;
27902772
const blob = new Blob( [ bufferView ], { type: source.mimeType } );
27912773
sourceURI = URL.createObjectURL( blob );
@@ -2836,9 +2818,6 @@ class GLTFParser {
28362818

28372819
if ( textureDef.name ) texture.name = textureDef.name;
28382820

2839-
// When there is definitely no alpha channel in the texture, set RGBFormat to save space.
2840-
if ( ! hasAlpha ) texture.format = RGBFormat;
2841-
28422821
const samplers = json.samplers || {};
28432822
const sampler = samplers[ textureDef.sampler ] || {};
28442823

‎examples/jsm/postprocessing/SSRPass.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { CopyShader } from '../shaders/CopyShader.js';
2424

2525
class SSRPass extends Pass {
2626

27-
constructor( { renderer, scene, camera, width, height, selects, encoding, bouncing = false, groundReflector } ) {
27+
constructor( { renderer, scene, camera, width, height, selects, bouncing = false, groundReflector } ) {
2828

2929
super();
3030

@@ -44,8 +44,6 @@ class SSRPass extends Pass {
4444
this.maxDistance = SSRShader.uniforms.maxDistance.value;
4545
this.thickness = SSRShader.uniforms.thickness.value;
4646

47-
this.encoding = encoding;
48-
4947
this.tempColor = new Color();
5048

5149
this._selects = selects;
@@ -359,7 +357,6 @@ class SSRPass extends Pass {
359357

360358
// render beauty and depth
361359

362-
if ( this.encoding ) this.beautyRenderTarget.texture.encoding = this.encoding;
363360
renderer.setRenderTarget( this.beautyRenderTarget );
364361
renderer.clear();
365362
if ( this.groundReflector ) {

‎examples/jsm/postprocessing/SSRrPass.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { CopyShader } from '../shaders/CopyShader.js';
2424

2525
class SSRrPass extends Pass {
2626

27-
constructor( { renderer, scene, camera, width, height, selects, encoding } ) {
27+
constructor( { renderer, scene, camera, width, height, selects } ) {
2828

2929
super();
3030

@@ -44,8 +44,6 @@ class SSRrPass extends Pass {
4444
this.maxDistance = SSRrShader.uniforms.maxDistance.value;
4545
this.surfDist = SSRrShader.uniforms.surfDist.value;
4646

47-
this.encoding = encoding;
48-
4947
this.tempColor = new Color();
5048

5149
this.selects = selects;
@@ -274,7 +272,6 @@ class SSRrPass extends Pass {
274272

275273
// render beauty and depth
276274

277-
if ( this.encoding ) this.beautyRenderTarget.texture.encoding = this.encoding;
278275
renderer.setRenderTarget( this.beautyRenderTarget );
279276
renderer.clear();
280277
this.scene.children.forEach( child => {
297 Bytes
Loading
-1.38 KB
Loading
Loading
-139 Bytes
Loading
-245 Bytes
Loading

‎examples/webgl_postprocessing_ssr.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import { GUI } from './jsm/libs/dat.gui.module.js';
2828
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
2929
import { SSRPass } from './jsm/postprocessing/SSRPass.js';
30+
import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
31+
import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js';
3032
import { ReflectorForSSRPass } from './jsm/objects/ReflectorForSSRPass.js';
3133

3234
import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
@@ -144,7 +146,6 @@
144146
// renderer
145147
renderer = new THREE.WebGLRenderer( { antialias: false } );
146148
renderer.setSize( window.innerWidth, window.innerHeight );
147-
renderer.outputEncoding = THREE.sRGBEncoding;
148149
container.appendChild( renderer.domElement );
149150

150151
//
@@ -171,12 +172,12 @@
171172
camera,
172173
width: innerWidth,
173174
height: innerHeight,
174-
encoding: THREE.sRGBEncoding,
175175
groundReflector: params.groundReflector ? groundReflector : null,
176176
selects: params.groundReflector ? selects : null
177177
} );
178178

179179
composer.addPass( ssrPass );
180+
composer.addPass( new ShaderPass( GammaCorrectionShader ) );
180181

181182
// GUI
182183

‎examples/webgl_postprocessing_ssrr.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import { GUI } from './jsm/libs/dat.gui.module.js';
2929
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
3030
import { SSRrPass } from './jsm/postprocessing/SSRrPass.js';
31+
import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
32+
import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js';
3133

3234
import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
3335

@@ -147,7 +149,6 @@
147149
// renderer
148150
renderer = new THREE.WebGLRenderer( { antialias: false } );
149151
renderer.setSize( window.innerWidth, window.innerHeight );
150-
renderer.outputEncoding = THREE.sRGBEncoding;
151152
renderer.autoClear = false;
152153
container.appendChild( renderer.domElement );
153154

@@ -177,11 +178,11 @@
177178
camera,
178179
width: innerWidth,
179180
height: innerHeight,
180-
encoding: THREE.sRGBEncoding,
181181
selects: selects
182182
} );
183183

184184
composer.addPass( ssrrPass );
185+
composer.addPass( new ShaderPass( GammaCorrectionShader ) );
185186

186187
// GUI
187188

‎src/extras/PMREMGenerator.js

+20-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
RGBDEncoding,
99
RGBEEncoding,
1010
RGBEFormat,
11+
RGBAFormat,
1112
RGBM16Encoding,
1213
RGBM7Encoding,
1314
UnsignedByteType,
@@ -345,6 +346,20 @@ class PMREMGenerator {
345346

346347
}
347348

349+
_setEncoding( uniform, texture ) {
350+
351+
if ( this._renderer.capabilities.isWebGL2 === true && texture.format === RGBAFormat && texture.type === UnsignedByteType && texture.encoding === sRGBEncoding ) {
352+
353+
uniform.value = ENCODINGS[ LinearEncoding ];
354+
355+
} else {
356+
357+
uniform.value = ENCODINGS[ texture.encoding ];
358+
359+
}
360+
361+
}
362+
348363
_textureToCubeUV( texture, cubeUVRenderTarget ) {
349364

350365
const renderer = this._renderer;
@@ -380,8 +395,8 @@ class PMREMGenerator {
380395

381396
}
382397

383-
uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ];
384-
uniforms[ 'outputEncoding' ].value = ENCODINGS[ cubeUVRenderTarget.texture.encoding ];
398+
this._setEncoding( uniforms[ 'inputEncoding' ], texture );
399+
this._setEncoding( uniforms[ 'outputEncoding' ], cubeUVRenderTarget.texture );
385400

386401
_setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX );
387402

@@ -512,8 +527,9 @@ class PMREMGenerator {
512527

513528
blurUniforms[ 'dTheta' ].value = radiansPerPixel;
514529
blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn;
515-
blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
516-
blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
530+
531+
this._setEncoding( blurUniforms[ 'inputEncoding' ], targetIn.texture );
532+
this._setEncoding( blurUniforms[ 'outputEncoding' ], targetIn.texture );
517533

518534
const outputSize = _sizeLods[ lodOut ];
519535
const x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize );

‎src/loaders/TextureLoader.js

-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { RGBAFormat, RGBFormat } from '../constants.js';
21
import { ImageLoader } from './ImageLoader.js';
32
import { Texture } from '../textures/Texture.js';
43
import { Loader } from './Loader.js';
@@ -22,11 +21,6 @@ class TextureLoader extends Loader {
2221
loader.load( url, function ( image ) {
2322

2423
texture.image = image;
25-
26-
// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
27-
const isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
28-
29-
texture.format = isJPEG ? RGBFormat : RGBAFormat;
3024
texture.needsUpdate = true;
3125

3226
if ( onLoad !== undefined ) {

‎src/renderers/webgl/WebGLPrograms.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, LinearEncoding, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping } from '../../constants.js';
1+
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, LinearEncoding, sRGBEncoding, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, RGBAFormat, UnsignedByteType } from '../../constants.js';
22
import { WebGLProgram } from './WebGLProgram.js';
33
import { ShaderLib } from '../shaders/ShaderLib.js';
44
import { UniformsUtils } from '../shaders/UniformsUtils.js';
@@ -106,6 +106,12 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
106106

107107
}
108108

109+
if ( isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding ) {
110+
111+
encoding = LinearEncoding; // disable inline decode for sRGB textures in WebGL 2
112+
113+
}
114+
109115
return encoding;
110116

111117
}

‎src/renderers/webgl/WebGLTextures.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBFormat, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping } from '../../constants.js';
1+
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBFormat, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, sRGBEncoding } from '../../constants.js';
22
import * as MathUtils from '../../math/MathUtils.js';
33
import { createElementNS } from '../../utils.js';
44

@@ -132,7 +132,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
132132

133133
}
134134

135-
function getInternalFormat( internalFormatName, glFormat, glType ) {
135+
function getInternalFormat( internalFormatName, glFormat, glType, encoding ) {
136136

137137
if ( isWebGL2 === false ) return glFormat;
138138

@@ -166,7 +166,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
166166

167167
if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
168168
if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
169-
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RGBA8;
169+
if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = ( encoding === sRGBEncoding ) ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
170170

171171
}
172172

@@ -532,7 +532,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
532532
glFormat = utils.convert( texture.format );
533533

534534
let glType = utils.convert( texture.type ),
535-
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
535+
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
536536

537537
setTextureParameters( textureType, texture, supportsMips );
538538

@@ -758,7 +758,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
758758
supportsMips = isPowerOfTwo( image ) || isWebGL2,
759759
glFormat = utils.convert( texture.format ),
760760
glType = utils.convert( texture.type ),
761-
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
761+
glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
762762

763763
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips );
764764

@@ -857,7 +857,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
857857

858858
const glFormat = utils.convert( texture.format );
859859
const glType = utils.convert( texture.type );
860-
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
860+
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
861861

862862
if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) {
863863

@@ -938,7 +938,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
938938

939939
const glFormat = utils.convert( texture.format );
940940
const glType = utils.convert( texture.type );
941-
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
941+
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
942942

943943
if ( isMultisample ) {
944944

@@ -1131,7 +1131,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
11311131

11321132
const glFormat = utils.convert( texture.format );
11331133
const glType = utils.convert( texture.type );
1134-
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
1134+
const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );
11351135
const samples = getRenderTargetSamples( renderTarget );
11361136
_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
11371137

‎src/textures/CubeTexture.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { Texture } from './Texture.js';
2-
import { CubeReflectionMapping, RGBFormat } from '../constants.js';
2+
import { CubeReflectionMapping } from '../constants.js';
33

44
class CubeTexture extends Texture {
55

66
constructor( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
77

88
images = images !== undefined ? images : [];
99
mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
10-
format = format !== undefined ? format : RGBFormat;
1110

1211
super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
1312

‎utils/build/rollup.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ export function glconstants() {
158158
MAX_SAMPLES: 36183,
159159
READ_FRAMEBUFFER: 36008,
160160
DRAW_FRAMEBUFFER: 36009,
161-
SAMPLE_ALPHA_TO_COVERAGE: 32926
161+
SAMPLE_ALPHA_TO_COVERAGE: 32926,
162+
SRGB8_ALPHA8: 35907
162163
};
163164

164165
return {

0 commit comments

Comments
 (0)
Please sign in to comment.