Skip to content

Commit

Permalink
HalfFloat PMREM (mrdoob#22998)
Browse files Browse the repository at this point in the history
* changed format

* PMREM RGBE->HalfFloat

* fixed toneMapping problem

* update screenshots

* Update WebGLRenderer.js

* Update WebGLRenderer.js

Co-authored-by: Michael Herzog <[email protected]>
  • Loading branch information
elalish and Mugen87 authored Dec 15, 2021
1 parent ab528ac commit 2768965
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 96 deletions.
Binary file modified examples/screenshots/webgl_materials_envmaps_hdr_nodes.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/screenshots/webgl_materials_envmaps_pmrem_nodes.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 12 additions & 72 deletions src/extras/PMREMGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import {
CubeUVReflectionMapping,
GammaEncoding,
LinearEncoding,
LinearFilter,
NoToneMapping,
NearestFilter,
NoBlending,
RGBDEncoding,
RGBEEncoding,
RGBAFormat,
RGBEFormat,
RGBM16Encoding,
RGBM7Encoding,
UnsignedByteType,
sRGBEncoding
sRGBEncoding,
HalfFloatType
} from '../constants.js';

import { BufferAttribute } from '../core/BufferAttribute.js';
Expand Down Expand Up @@ -234,12 +234,12 @@ class PMREMGenerator {
_allocateTargets( texture ) { // warning: null texture is valid

const params = {
magFilter: NearestFilter,
minFilter: NearestFilter,
magFilter: LinearFilter,
minFilter: LinearFilter,
generateMipmaps: false,
type: UnsignedByteType,
format: RGBEFormat,
encoding: _isLDR( texture ) ? texture.encoding : RGBEEncoding,
type: HalfFloatType,
format: RGBAFormat,
encoding: LinearEncoding,
depthBuffer: false
};

Expand Down Expand Up @@ -267,12 +267,10 @@ class PMREMGenerator {
const renderer = this._renderer;

const originalAutoClear = renderer.autoClear;
const outputEncoding = renderer.outputEncoding;
const toneMapping = renderer.toneMapping;
renderer.getClearColor( _clearColor );

renderer.toneMapping = NoToneMapping;
renderer.outputEncoding = LinearEncoding;
renderer.autoClear = false;

const backgroundMaterial = new MeshBasicMaterial( {
Expand Down Expand Up @@ -342,7 +340,6 @@ class PMREMGenerator {
backgroundBox.material.dispose();

renderer.toneMapping = toneMapping;
renderer.outputEncoding = outputEncoding;
renderer.autoClear = originalAutoClear;
scene.background = background;

Expand Down Expand Up @@ -400,7 +397,6 @@ class PMREMGenerator {
}

this._setEncoding( uniforms[ 'inputEncoding' ], texture );
this._setEncoding( uniforms[ 'outputEncoding' ], cubeUVRenderTarget.texture );

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

Expand Down Expand Up @@ -532,9 +528,6 @@ class PMREMGenerator {
blurUniforms[ 'dTheta' ].value = radiansPerPixel;
blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn;

this._setEncoding( blurUniforms[ 'inputEncoding' ], targetIn.texture );
this._setEncoding( blurUniforms[ 'outputEncoding' ], targetIn.texture );

const outputSize = _sizeLods[ lodOut ];
const x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize );
const y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + 2 * outputSize * ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 );
Expand All @@ -547,14 +540,6 @@ class PMREMGenerator {

}

function _isLDR( texture ) {

if ( texture === undefined || texture.type !== UnsignedByteType ) return false;

return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding;

}

function _createPlanes() {

const _lodPlanes = [];
Expand Down Expand Up @@ -667,9 +652,7 @@ function _getBlurShader( maxSamples ) {
'latitudinal': { value: false },
'dTheta': { value: 0 },
'mipInt': { value: 0 },
'poleAxis': { value: poleAxis },
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
'poleAxis': { value: poleAxis }
},

vertexShader: _getCommonVertexShader(),
Expand Down Expand Up @@ -735,8 +718,6 @@ function _getBlurShader( maxSamples ) {
}
gl_FragColor = linearToOutputTexel( gl_FragColor );
}
`,

Expand All @@ -760,8 +741,7 @@ function _getEquirectShader() {
uniforms: {
'envMap': { value: null },
'texelSize': { value: texelSize },
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }
},

vertexShader: _getCommonVertexShader(),
Expand Down Expand Up @@ -801,8 +781,6 @@ function _getEquirectShader() {
vec3 bm = mix( bl, br, f.x );
gl_FragColor.rgb = mix( tm, bm, f.y );
gl_FragColor = linearToOutputTexel( gl_FragColor );
}
`,

Expand All @@ -824,8 +802,7 @@ function _getCubemapShader() {

uniforms: {
'envMap': { value: null },
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }
},

vertexShader: _getCommonVertexShader(),
Expand All @@ -843,9 +820,7 @@ function _getCubemapShader() {
void main() {
gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
gl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb;
gl_FragColor = linearToOutputTexel( gl_FragColor );
gl_FragColor = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) );
}
`,
Expand Down Expand Up @@ -928,7 +903,6 @@ function _getEncodings() {
return /* glsl */`
uniform int inputEncoding;
uniform int outputEncoding;
#include <encodings_pars_fragment>
Expand Down Expand Up @@ -966,40 +940,6 @@ function _getEncodings() {
}
vec4 linearToOutputTexel( vec4 value ) {
if ( outputEncoding == 0 ) {
return value;
} else if ( outputEncoding == 1 ) {
return LinearTosRGB( value );
} else if ( outputEncoding == 2 ) {
return LinearToRGBE( value );
} else if ( outputEncoding == 3 ) {
return LinearToRGBM( value, 7.0 );
} else if ( outputEncoding == 4 ) {
return LinearToRGBM( value, 16.0 );
} else if ( outputEncoding == 5 ) {
return LinearToRGBD( value, 256.0 );
} else {
return LinearToGamma( value, 2.2 );
}
}
vec4 envMapTexelToLinear( vec4 color ) {
return inputTexelToLinear( color );
Expand Down
6 changes: 6 additions & 0 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,7 @@ function WebGLRenderer( parameters = {} ) {
materialProperties.numIntersection = parameters.numClipIntersection;
materialProperties.vertexAlphas = parameters.vertexAlphas;
materialProperties.vertexTangents = parameters.vertexTangents;
materialProperties.toneMapping = parameters.toneMapping;

}

Expand All @@ -1428,6 +1429,7 @@ function WebGLRenderer( parameters = {} ) {
const morphTargets = !! geometry.morphAttributes.position;
const morphNormals = !! geometry.morphAttributes.normal;
const morphTargetsCount = !! geometry.morphAttributes.position ? geometry.morphAttributes.position.length : 0;
const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping;

const materialProperties = properties.get( material );
const lights = currentRenderState.state.lights;
Expand Down Expand Up @@ -1509,6 +1511,10 @@ function WebGLRenderer( parameters = {} ) {

needsProgramChange = true;

} else if ( materialProperties.toneMapping !== toneMapping ) {

needsProgramChange = true;

} else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) {

needsProgramChange = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ export default /* glsl */`
float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 );
vec2 f = fract( uv );
uv += 0.5 - f;
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5;
if ( face > 2.0 ) {
Expand All @@ -117,25 +113,7 @@ export default /* glsl */`
uv *= texelSize;
vec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;
uv.x += texelSize;
vec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;
uv.y += texelSize;
vec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;
uv.x -= texelSize;
vec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;
vec3 tm = mix( tl, tr, f.x );
vec3 bm = mix( bl, br, f.x );
return mix( tm, bm, f.y );
return texture2D( envMap, uv ).rgb;
}
Expand Down

0 comments on commit 2768965

Please sign in to comment.