未验证 提交 c7d88958 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #18004 from elalish/pmrem

PMREM Upgrade
/**
* @author Prashant Sharma / spidersharma03
* @author Ben Houston / bhouston, https://clara.io
*
* This class takes the cube lods(corresponding to different roughness values), and creates a single cubeUV
* Texture. The format for a given roughness set of faces is simply::
* +X+Y+Z
* -X-Y-Z
* For every roughness a mip map chain is also saved, which is essential to remove the texture artifacts due to
* minification.
* Right now for every face a PlaneMesh is drawn, which leads to a lot of geometry draw calls, but can be replaced
* later by drawing a single buffer and by sending the appropriate faceIndex via vertex attributes.
* The arrangement of the faces is fixed, as assuming this arrangement, the sampling function has been written.
*/
THREE.PMREMCubeUVPacker = ( function () {
var camera = new THREE.OrthographicCamera();
var scene = new THREE.Scene();
var shader = getShader();
var PMREMCubeUVPacker = function ( cubeTextureLods ) {
this.cubeLods = cubeTextureLods;
var size = cubeTextureLods[ 0 ].width * 4;
var sourceTexture = cubeTextureLods[ 0 ].texture;
var params = {
format: sourceTexture.format,
magFilter: sourceTexture.magFilter,
minFilter: sourceTexture.minFilter,
type: sourceTexture.type,
generateMipmaps: sourceTexture.generateMipmaps,
anisotropy: sourceTexture.anisotropy,
encoding: ( sourceTexture.encoding === THREE.RGBEEncoding ) ? THREE.RGBM16Encoding : sourceTexture.encoding
};
if ( params.encoding === THREE.RGBM16Encoding ) {
params.magFilter = THREE.LinearFilter;
params.minFilter = THREE.LinearFilter;
}
this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size, params );
this.CubeUVRenderTarget.texture.name = "PMREMCubeUVPacker.cubeUv";
this.CubeUVRenderTarget.texture.mapping = THREE.CubeUVReflectionMapping;
this.objects = [];
var geometry = new THREE.PlaneBufferGeometry( 1, 1 );
var faceOffsets = [];
faceOffsets.push( new THREE.Vector2( 0, 0 ) );
faceOffsets.push( new THREE.Vector2( 1, 0 ) );
faceOffsets.push( new THREE.Vector2( 2, 0 ) );
faceOffsets.push( new THREE.Vector2( 0, 1 ) );
faceOffsets.push( new THREE.Vector2( 1, 1 ) );
faceOffsets.push( new THREE.Vector2( 2, 1 ) );
var textureResolution = size;
size = cubeTextureLods[ 0 ].width;
var offset2 = 0;
var c = 4.0;
this.numLods = Math.log( cubeTextureLods[ 0 ].width ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
for ( var i = 0; i < this.numLods; i ++ ) {
var offset1 = ( textureResolution - textureResolution / c ) * 0.5;
if ( size > 16 ) c *= 2;
var nMips = size > 16 ? 6 : 1;
var mipOffsetX = 0;
var mipOffsetY = 0;
var mipSize = size;
for ( var j = 0; j < nMips; j ++ ) {
// Mip Maps
for ( var k = 0; k < 6; k ++ ) {
// 6 Cube Faces
var material = shader.clone();
material.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
material.envMap = this.cubeLods[ i ].texture;
material.uniforms[ 'faceIndex' ].value = k;
material.uniforms[ 'mapSize' ].value = mipSize;
var planeMesh = new THREE.Mesh( geometry, material );
planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX;
planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY;
planeMesh.material.side = THREE.BackSide;
planeMesh.scale.setScalar( mipSize );
this.objects.push( planeMesh );
}
mipOffsetY += 1.75 * mipSize;
mipOffsetX += 1.25 * mipSize;
mipSize /= 2;
}
offset2 += 2 * size;
if ( size > 16 ) size /= 2;
}
};
PMREMCubeUVPacker.prototype = {
constructor: PMREMCubeUVPacker,
update: function ( renderer ) {
var size = this.cubeLods[ 0 ].width * 4;
// top and bottom are swapped for some reason?
camera.left = - size * 0.5;
camera.right = size * 0.5;
camera.top = - size * 0.5;
camera.bottom = size * 0.5;
camera.near = 0;
camera.far = 1;
camera.updateProjectionMatrix();
for ( var i = 0; i < this.objects.length; i ++ ) {
scene.add( this.objects[ i ] );
}
var gammaInput = renderer.gammaInput;
var gammaOutput = renderer.gammaOutput;
var toneMapping = renderer.toneMapping;
var toneMappingExposure = renderer.toneMappingExposure;
var currentRenderTarget = renderer.getRenderTarget();
renderer.gammaInput = false;
renderer.gammaOutput = false;
renderer.toneMapping = THREE.LinearToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.setRenderTarget( this.CubeUVRenderTarget );
renderer.render( scene, camera );
renderer.setRenderTarget( currentRenderTarget );
renderer.toneMapping = toneMapping;
renderer.toneMappingExposure = toneMappingExposure;
renderer.gammaInput = gammaInput;
renderer.gammaOutput = gammaOutput;
for ( var i = 0; i < this.objects.length; i ++ ) {
scene.remove( this.objects[ i ] );
}
},
dispose: function () {
for ( var i = 0, l = this.objects.length; i < l; i ++ ) {
this.objects[ i ].material.dispose();
}
this.objects[ 0 ].geometry.dispose();
}
};
function getShader() {
var shaderMaterial = new THREE.ShaderMaterial( {
uniforms: {
"faceIndex": { value: 0 },
"mapSize": { value: 0 },
"envMap": { value: null },
"testColor": { value: new THREE.Vector3( 1, 1, 1 ) }
},
vertexShader:
"precision highp float;\
varying vec2 vUv;\
void main() {\
vUv = uv;\
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\
}",
fragmentShader:
"precision highp float;\
varying vec2 vUv;\
uniform samplerCube envMap;\
uniform float mapSize;\
uniform vec3 testColor;\
uniform int faceIndex;\
\
void main() {\
vec3 sampleDirection;\
vec2 uv = vUv;\
uv = uv * 2.0 - 1.0;\
uv.y *= -1.0;\
if(faceIndex == 0) {\
sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\
} else if(faceIndex == 1) {\
sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\
} else if(faceIndex == 2) {\
sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\
} else if(faceIndex == 3) {\
sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\
} else if(faceIndex == 4) {\
sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\
} else {\
sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
}\
vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
gl_FragColor = linearToOutputTexel( color );\
}",
blending: THREE.NoBlending
} );
shaderMaterial.type = 'PMREMCubeUVPacker';
return shaderMaterial;
}
return PMREMCubeUVPacker;
} )();
此差异已折叠。
import { CubeTexture, Renderer, WebGLRenderTarget } from '../../../src/Three';
export class PMREMCubeUVPacker {
CubeUVRenderTarget:WebGLRenderTarget;
constructor( cubeTextureLods: CubeTexture[] );
update( renderer:Renderer ): void;
dispose(): void;
}
/**
* @author Prashant Sharma / spidersharma03
* @author Ben Houston / bhouston, https://clara.io
*
* This class takes the cube lods(corresponding to different roughness values), and creates a single cubeUV
* Texture. The format for a given roughness set of faces is simply::
* +X+Y+Z
* -X-Y-Z
* For every roughness a mip map chain is also saved, which is essential to remove the texture artifacts due to
* minification.
* Right now for every face a PlaneMesh is drawn, which leads to a lot of geometry draw calls, but can be replaced
* later by drawing a single buffer and by sending the appropriate faceIndex via vertex attributes.
* The arrangement of the faces is fixed, as assuming this arrangement, the sampling function has been written.
*/
import {
BackSide,
CubeUVReflectionMapping,
LinearFilter,
LinearToneMapping,
Mesh,
NoBlending,
OrthographicCamera,
PlaneBufferGeometry,
RGBEEncoding,
RGBM16Encoding,
Scene,
ShaderMaterial,
Vector2,
Vector3,
WebGLRenderTarget
} from "../../../build/three.module.js";
var PMREMCubeUVPacker = ( function () {
var camera = new OrthographicCamera();
var scene = new Scene();
var shader = getShader();
var PMREMCubeUVPacker = function ( cubeTextureLods ) {
this.cubeLods = cubeTextureLods;
var size = cubeTextureLods[ 0 ].width * 4;
var sourceTexture = cubeTextureLods[ 0 ].texture;
var params = {
format: sourceTexture.format,
magFilter: sourceTexture.magFilter,
minFilter: sourceTexture.minFilter,
type: sourceTexture.type,
generateMipmaps: sourceTexture.generateMipmaps,
anisotropy: sourceTexture.anisotropy,
encoding: ( sourceTexture.encoding === RGBEEncoding ) ? RGBM16Encoding : sourceTexture.encoding
};
if ( params.encoding === RGBM16Encoding ) {
params.magFilter = LinearFilter;
params.minFilter = LinearFilter;
}
this.CubeUVRenderTarget = new WebGLRenderTarget( size, size, params );
this.CubeUVRenderTarget.texture.name = "PMREMCubeUVPacker.cubeUv";
this.CubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
this.objects = [];
var geometry = new PlaneBufferGeometry( 1, 1 );
var faceOffsets = [];
faceOffsets.push( new Vector2( 0, 0 ) );
faceOffsets.push( new Vector2( 1, 0 ) );
faceOffsets.push( new Vector2( 2, 0 ) );
faceOffsets.push( new Vector2( 0, 1 ) );
faceOffsets.push( new Vector2( 1, 1 ) );
faceOffsets.push( new Vector2( 2, 1 ) );
var textureResolution = size;
size = cubeTextureLods[ 0 ].width;
var offset2 = 0;
var c = 4.0;
this.numLods = Math.log( cubeTextureLods[ 0 ].width ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
for ( var i = 0; i < this.numLods; i ++ ) {
var offset1 = ( textureResolution - textureResolution / c ) * 0.5;
if ( size > 16 ) c *= 2;
var nMips = size > 16 ? 6 : 1;
var mipOffsetX = 0;
var mipOffsetY = 0;
var mipSize = size;
for ( var j = 0; j < nMips; j ++ ) {
// Mip Maps
for ( var k = 0; k < 6; k ++ ) {
// 6 Cube Faces
var material = shader.clone();
material.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
material.envMap = this.cubeLods[ i ].texture;
material.uniforms[ 'faceIndex' ].value = k;
material.uniforms[ 'mapSize' ].value = mipSize;
var planeMesh = new Mesh( geometry, material );
planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX;
planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY;
planeMesh.material.side = BackSide;
planeMesh.scale.setScalar( mipSize );
this.objects.push( planeMesh );
}
mipOffsetY += 1.75 * mipSize;
mipOffsetX += 1.25 * mipSize;
mipSize /= 2;
}
offset2 += 2 * size;
if ( size > 16 ) size /= 2;
}
};
PMREMCubeUVPacker.prototype = {
constructor: PMREMCubeUVPacker,
update: function ( renderer ) {
var size = this.cubeLods[ 0 ].width * 4;
// top and bottom are swapped for some reason?
camera.left = - size * 0.5;
camera.right = size * 0.5;
camera.top = - size * 0.5;
camera.bottom = size * 0.5;
camera.near = 0;
camera.far = 1;
camera.updateProjectionMatrix();
for ( var i = 0; i < this.objects.length; i ++ ) {
scene.add( this.objects[ i ] );
}
var gammaInput = renderer.gammaInput;
var gammaOutput = renderer.gammaOutput;
var toneMapping = renderer.toneMapping;
var toneMappingExposure = renderer.toneMappingExposure;
var currentRenderTarget = renderer.getRenderTarget();
renderer.gammaInput = false;
renderer.gammaOutput = false;
renderer.toneMapping = LinearToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.setRenderTarget( this.CubeUVRenderTarget );
renderer.render( scene, camera );
renderer.setRenderTarget( currentRenderTarget );
renderer.toneMapping = toneMapping;
renderer.toneMappingExposure = toneMappingExposure;
renderer.gammaInput = gammaInput;
renderer.gammaOutput = gammaOutput;
for ( var i = 0; i < this.objects.length; i ++ ) {
scene.remove( this.objects[ i ] );
}
},
dispose: function () {
for ( var i = 0, l = this.objects.length; i < l; i ++ ) {
this.objects[ i ].material.dispose();
}
this.objects[ 0 ].geometry.dispose();
}
};
function getShader() {
var shaderMaterial = new ShaderMaterial( {
uniforms: {
"faceIndex": { value: 0 },
"mapSize": { value: 0 },
"envMap": { value: null },
"testColor": { value: new Vector3( 1, 1, 1 ) }
},
vertexShader:
"precision highp float;\
varying vec2 vUv;\
void main() {\
vUv = uv;\
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\
}",
fragmentShader:
"precision highp float;\
varying vec2 vUv;\
uniform samplerCube envMap;\
uniform float mapSize;\
uniform vec3 testColor;\
uniform int faceIndex;\
\
void main() {\
vec3 sampleDirection;\
vec2 uv = vUv;\
uv = uv * 2.0 - 1.0;\
uv.y *= -1.0;\
if(faceIndex == 0) {\
sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\
} else if(faceIndex == 1) {\
sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\
} else if(faceIndex == 2) {\
sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\
} else if(faceIndex == 3) {\
sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\
} else if(faceIndex == 4) {\
sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\
} else {\
sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
}\
vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
gl_FragColor = linearToOutputTexel( color );\
}",
blending: NoBlending
} );
shaderMaterial.type = 'PMREMCubeUVPacker';
return shaderMaterial;
}
return PMREMCubeUVPacker;
} )();
export { PMREMCubeUVPacker };
import {
Renderer,
RenderTarget,
WebGLRenderer,
WebGLRenderTarget,
Texture,
CubeTexture
CubeTexture,
Scene
} from '../../../src/Three';
export class PMREMGenerator {
cubeLods:CubeTexture[];
constructor( sourceTexture:Texture, samplesPerLevel?:number, resolution?:number );
update( renderer:Renderer ): void;
renderToCubeMapTarget( renderer:Renderer, renderTarget:any ): void;
renderToCubeMapTargetFace( renderer:Renderer, renderTarget:RenderTarget, faceIndex:number ): void;
constructor( renderer:WebGLRenderer );
fromScene( scene:Scene, sigma?:number, near?:number, far?:number ): WebGLRenderTarget;
fromEquirectangular( equirectangular:Texture ): WebGLRenderTarget;
fromCubemap( cubemap:CubeTexture ): WebGLRenderTarget;
dispose(): void;
}
......@@ -29,7 +29,6 @@
import * as THREE from '../build/three.module.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var scene, camera, renderer, envMap, radianceMap;
var right = 8;
......@@ -75,8 +74,8 @@
// camera
camera = new THREE.OrthographicCamera( - right, right, right / aspect, - right / aspect, 1, 30 );
camera.position.set( 0, 0, 9 );
camera = new THREE.PerspectiveCamera( 40, aspect, 1, 30 );
camera.position.set( 0, 0, 18 );
}
......@@ -110,34 +109,16 @@
function createEnvironment() {
var envScene = new THREE.Scene();
envScene.background = new THREE.Color( 0xcccccc );
var cubeCamera = new THREE.CubeCamera( 1, 100, 256, 256 );
cubeCamera.update( renderer, envScene );
envMap = cubeCamera.renderTarget.texture;
scene.background = envScene.background;
}
function getRadiance() {
return new Promise( function ( resolve ) {
var pmremGenerator = new PMREMGenerator( envMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var cubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var envScene = new THREE.Scene();
envScene.background = new THREE.Color( 0xcccccc );
var pmremGenerator = new PMREMGenerator( renderer );
radianceMap = pmremGenerator.fromScene( envScene ).texture;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
radianceMap = cubeRenderTarget.texture;
scene.background = radianceMap;
resolve();
......@@ -147,11 +128,13 @@
function onResize() {
var aspect = window.innerWidth / window.innerHeight;
camera.top = right / aspect;
camera.bottom = - camera.top;
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setSize( width, height );
}
......@@ -170,7 +153,6 @@
Promise.resolve()
.then( init )
.then( createEnvironment )
.then( getRadiance )
.then( createObjects )
.then( animate );
......
......@@ -25,7 +25,6 @@
import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
import { RGBELoader } from './jsm/loaders/RGBELoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var container, stats, controls;
var camera, scene, renderer;
......@@ -46,22 +45,13 @@
new RGBELoader()
.setDataType( THREE.UnsignedByteType )
.setPath( 'textures/equirectangular/' )
.load( 'pedestrian_overpass_2k.hdr', function ( texture ) {
.load( 'pedestrian_overpass_1k.hdr', function ( texture ) {
var options = {
minFilter: texture.minFilter,
magFilter: texture.magFilter
};
scene.background = new THREE.WebGLRenderTargetCube( 1024, 1024, options ).fromEquirectangularTexture( renderer, texture );
var pmremGenerator = new PMREMGenerator( scene.background.texture );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var pmremGenerator = new PMREMGenerator( renderer );
var envMap = pmremGenerator.fromEquirectangular( texture ).texture;
pmremGenerator.dispose();
var envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
scene.background = envMap;
// model
......@@ -82,9 +72,6 @@
} );
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
renderer = new THREE.WebGLRenderer( { antialias: true } );
......
......@@ -27,7 +27,6 @@
import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
import { RGBELoader } from './jsm/loaders/RGBELoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var orbitControls;
var container, camera, scene, renderer, loader;
......@@ -156,25 +155,13 @@
new RGBELoader()
.setDataType( THREE.UnsignedByteType )
.setPath( 'textures/equirectangular/' )
.load( 'venice_sunset_2k.hdr', function ( texture ) {
var options = {
minFilter: texture.minFilter,
magFilter: texture.magFilter
};
background = new THREE.WebGLRenderTargetCube( 1024, 1024, options ).fromEquirectangularTexture( renderer, texture );
var pmremGenerator = new PMREMGenerator( background.texture );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
.load( 'venice_sunset_1k.hdr', function ( texture ) {
var pmremGenerator = new PMREMGenerator( renderer );
envMap = pmremGenerator.fromEquirectangular( texture ).texture;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
background = envMap;
//
......
......@@ -43,7 +43,6 @@
import { RGBELoader } from './jsm/loaders/RGBELoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var camera, scene, renderer;
var stats, carModel, materialsLib, envMap;
......@@ -92,20 +91,11 @@
magFilter: texture.magFilter
};
scene.background = new THREE.WebGLRenderTargetCube( 1024, 1024, options ).fromEquirectangularTexture( renderer, texture );
envMap = scene.background;
var pmremGenerator = new PMREMGenerator( scene.background.texture );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
var pmremGenerator = new PMREMGenerator( renderer );
envMap = pmremGenerator.fromEquirectangular( texture ).texture;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
scene.background = envMap;
//
......
......@@ -21,7 +21,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { EXRLoader } from './jsm/loaders/EXRLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var params = {
envMap: 'EXR',
......@@ -73,6 +72,13 @@
planeMesh.rotation.x = - Math.PI * 0.5;
scene.add( planeMesh );
var pmremGenerator = new PMREMGenerator( renderer );
THREE.DefaultLoadingManager.onLoad = function ( ) {
pmremGenerator.dispose();
}
new EXRLoader()
.setDataType( THREE.FloatType )
.load( 'textures/piz_compressed.exr', function ( texture ) {
......@@ -83,19 +89,11 @@
magFilter: THREE.LinearFilter
};
exrBackground = new THREE.WebGLRenderTargetCube( 512, 512, options ).fromEquirectangularTexture( renderer, texture );
exrCubeRenderTarget = pmremGenerator.fromEquirectangular( texture );
var pmremGenerator = new PMREMGenerator( exrBackground.texture );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
exrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
exrBackground = exrCubeRenderTarget.texture;
texture.dispose();
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
......@@ -103,19 +101,11 @@
texture.encoding = THREE.sRGBEncoding;
pngBackground = new THREE.WebGLRenderTargetCube( 512, 512 ).fromEquirectangularTexture( renderer, texture );
var pmremGenerator = new PMREMGenerator( pngBackground.texture );
pmremGenerator.update( renderer );
pngCubeRenderTarget = pmremGenerator.fromEquirectangular( texture );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
pngCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
pngBackground = pngCubeRenderTarget.texture;
texture.dispose();
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
......
......@@ -24,7 +24,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var params = {
envMap: 'HDR',
......@@ -78,27 +77,24 @@
planeMesh.rotation.x = - Math.PI * 0.5;
scene.add( planeMesh );
var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
var pmremGenerator = new PMREMGenerator( renderer );
THREE.DefaultLoadingManager.onLoad = function ( ) {
pmremGenerator.dispose();
}
var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
hdrCubeMap = new HDRCubeTextureLoader()
.setPath( './textures/cube/pisaHDR/' )
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function () {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
hdrCubeMap.magFilter = THREE.LinearFilter;
hdrCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
var ldrUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
......@@ -106,18 +102,9 @@
.setPath( './textures/cube/pisa/' )
.load( ldrUrls, function () {
ldrCubeMap.encoding = THREE.sRGBEncoding;
var pmremGenerator = new PMREMGenerator( ldrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
ldrCubeMap.encoding = THREE.GammaEncoding;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
ldrCubeRenderTarget = pmremGenerator.fromCubemap( ldrCubeMap );
} );
......@@ -130,20 +117,11 @@
rgbmCubeMap.encoding = THREE.RGBM16Encoding;
rgbmCubeMap.format = THREE.RGBAFormat;
var pmremGenerator = new PMREMGenerator( rgbmCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
rgbmCubeRenderTarget = pmremGenerator.fromCubemap( rgbmCubeMap );
rgbmCubeMap.magFilter = THREE.LinearFilter;
rgbmCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
renderer.setPixelRatio( window.devicePixelRatio );
......
......@@ -41,7 +41,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
import { MeshStandardNodeMaterial } from './jsm/nodes/Nodes.js';
var params = {
......@@ -103,26 +102,24 @@
planeMesh.rotation.x = - Math.PI * 0.5;
scene.add( planeMesh );
var pmremGenerator = new PMREMGenerator( renderer );
THREE.DefaultLoadingManager.onLoad = function ( ) {
pmremGenerator.dispose();
}
var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
hdrCubeMap = new HDRCubeTextureLoader()
.setPath( './textures/cube/pisaHDR/' )
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function () {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
hdrCubeMap.magFilter = THREE.LinearFilter;
hdrCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
var ldrUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
......@@ -132,16 +129,7 @@
ldrCubeMap.encoding = THREE.GammaEncoding;
var pmremGenerator = new PMREMGenerator( ldrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
ldrCubeRenderTarget = pmremGenerator.fromCubemap( ldrCubeMap );
} );
......@@ -154,20 +142,11 @@
rgbmCubeMap.encoding = THREE.RGBM16Encoding;
rgbmCubeMap.format = THREE.RGBAFormat;
var pmremGenerator = new PMREMGenerator( rgbmCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
rgbmCubeRenderTarget = pmremGenerator.fromCubemap( rgbmCubeMap );
rgbmCubeMap.magFilter = THREE.LinearFilter;
rgbmCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
renderer.setPixelRatio( window.devicePixelRatio );
......
......@@ -41,7 +41,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
import {
StandardNodeMaterial,
......@@ -74,13 +73,10 @@
nodeTextureSize.value = textureSize;
var pmremGenerator = new PMREMGenerator( hdrCubeMap, undefined, textureSize / 4 );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var pmremGenerator = new PMREMGenerator( renderer );
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
nodeTexture.value = hdrCubeRenderTarget.texture;
hdrCubeMap.magFilter = THREE.LinearFilter;
......@@ -89,9 +85,6 @@
planeMesh.material.map = hdrCubeRenderTarget.texture;
planeMesh.material.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
}
function init() {
......
......@@ -24,7 +24,6 @@
import { TeapotBufferGeometry } from './jsm/geometries/TeapotBufferGeometry.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
import { NodeMaterialLoader, NodeMaterialLoaderUtils } from './jsm/loaders/NodeMaterialLoader.js';
......@@ -70,7 +69,7 @@
}
var premTexture, pmremCube, pmremGenerator, pmremCubeUVPacker, premSize = 1024;
var premTexture, pmremCube, pmremGenerator, premSize = 1024;
function updatePREM( textureCube ) {
......@@ -82,24 +81,17 @@
var magFilter = pmremCube.magFilter;
var generateMipmaps = pmremCube.generateMipmaps;
pmremGenerator = new PMREMGenerator( pmremCube, undefined, premSize / 4 );
pmremGenerator.update( renderer );
pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var pmremGenerator = new PMREMGenerator( renderer );
premTexture = pmremGenerator.fromCubemap( pmremCube ).texture;
pmremGenerator.dispose();
pmremCube.minFilter = minFilter;
pmremCube.magFilter = magFilter;
pmremCube.generateMipmaps = generateMipmaps;
pmremCube.needsUpdate = true;
premTexture = pmremCubeUVPacker.CubeUVRenderTarget.texture;
library[ premTexture.uuid ] = premTexture;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
}
var cubemap = function () {
......
......@@ -22,7 +22,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var container, stats;
......@@ -53,13 +52,9 @@
.load( [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ],
function ( hdrCubeMap ) {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
var hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
var geometry = new THREE.SphereBufferGeometry( 80, 64, 32 );
......@@ -160,9 +155,6 @@
hdrCubeMap.needsUpdate = true;
scene.background = hdrCubeMap;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
}
);
......
......@@ -21,7 +21,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var params = {
color: 0xffffff,
......@@ -74,20 +73,13 @@
//
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
hdrCubeMap.magFilter = THREE.LinearFilter;
hdrCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
//
var geometry = new THREE.SphereBufferGeometry( 20, 64, 32 );
......
......@@ -25,7 +25,6 @@
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var container, stats;
var params = {
......@@ -129,20 +128,14 @@
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function ( hdrCubeMap ) {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
gemFrontMaterial.envMap = gemBackMaterial.envMap = hdrCubeRenderTarget.texture;
gemFrontMaterial.needsUpdate = gemBackMaterial.needsUpdate = true;
hdrCubeMap.dispose();
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
......
......@@ -22,7 +22,6 @@
import { TrackballControls } from './jsm/controls/TrackballControls.js';
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var statsEnabled = true;
......@@ -107,13 +106,9 @@
rgbmCubeMap.encoding = THREE.RGBM16Encoding;
rgbmCubeMap.format = THREE.RGBAFormat;
var pmremGenerator = new PMREMGenerator( rgbmCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
var rgbmCubeRenderTarget = pmremGenerator.fromCubemap( rgbmCubeMap );
pmremGenerator.dispose();
material.envMap = rgbmCubeRenderTarget.texture;
material.needsUpdate = true; // is this needed?
......@@ -122,9 +117,6 @@
rgbmCubeMap.needsUpdate = true;
scene.background = rgbmCubeMap;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
//
......
......@@ -21,7 +21,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var container, stats;
......@@ -65,13 +64,9 @@
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function ( hdrCubeMap ) {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
// Materials
......@@ -124,9 +119,6 @@
hdrCubeMap.needsUpdate = true;
scene.background = hdrCubeMap;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
function addLabel( name, location ) {
......
......@@ -21,7 +21,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var container, stats;
......@@ -71,13 +70,9 @@
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function ( hdrCubeMap ) {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var pmremGenerator = new PMREMGenerator( renderer );
hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
pmremGenerator.dispose();
var bumpScale = 1;
var cubeWidth = 400;
......@@ -130,9 +125,6 @@
hdrCubeMap.needsUpdate = true;
scene.background = hdrCubeMap;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
function addLabel( name, location ) {
......
......@@ -21,7 +21,6 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './jsm/postprocessing/RenderPass.js';
......@@ -146,18 +145,12 @@
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function ( hdrCubeMap ) {
var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
standardMaterial.envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
var pmremGenerator = new PMREMGenerator( renderer );
standardMaterial.envMap = pmremGenerator.fromCubemap( hdrCubeMap ).texture;
standardMaterial.needsUpdate = true;
hdrCubeMap.dispose();
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
......
......@@ -1990,6 +1990,10 @@ function WebGLRenderer( parameters ) {
m_uniforms.color.value.copy( material.color );
m_uniforms.opacity.value = material.opacity;
} else if ( material.envMap ) {
refreshUniformsCommon( m_uniforms, material );
}
// RectAreaLight Texture
......
export default /* glsl */`
#ifdef ENVMAP_TYPE_CUBE_UV
#define cubeUV_textureSize (1024.0)
int getFaceFromDirection(vec3 direction) {
vec3 absDirection = abs(direction);
int face = -1;
if( absDirection.x > absDirection.z ) {
if(absDirection.x > absDirection.y )
face = direction.x > 0.0 ? 0 : 3;
else
face = direction.y > 0.0 ? 1 : 4;
}
else {
if(absDirection.z > absDirection.y )
face = direction.z > 0.0 ? 2 : 5;
else
face = direction.y > 0.0 ? 1 : 4;
}
return face;
#define cubeUV_maxMipLevel 8.0
#define cubeUV_minMipLevel 4.0
#define cubeUV_maxTileSize 256.0
#define cubeUV_minTileSize 16.0
// These shader functions convert between the UV coordinates of a single face of
// a cubemap, the 0-5 integer index of a cube face, and the direction vector for
// sampling a textureCube (not generally normalized).
float getFace(vec3 direction) {
vec3 absDirection = abs(direction);
float face = -1.0;
if (absDirection.x > absDirection.z) {
if (absDirection.x > absDirection.y)
face = direction.x > 0.0 ? 0.0 : 3.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
} else {
if (absDirection.z > absDirection.y)
face = direction.z > 0.0 ? 2.0 : 5.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
}
return face;
}
#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)
#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))
vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {
float scale = exp2(cubeUV_maxLods1 - roughnessLevel);
float dxRoughness = dFdx(roughness);
float dyRoughness = dFdy(roughness);
vec3 dx = dFdx( vec * scale * dxRoughness );
vec3 dy = dFdy( vec * scale * dyRoughness );
float d = max( dot( dx, dx ), dot( dy, dy ) );
// Clamp the value to the max mip level counts. hard coded to 6 mips
d = clamp(d, 1.0, cubeUV_rangeClamp);
float mipLevel = 0.5 * log2(d);
return vec2(floor(mipLevel), fract(mipLevel));
vec2 getUV(vec3 direction, float face) {
vec2 uv;
if (face == 0.0) {
uv = vec2(-direction.z, direction.y) / abs(direction.x);
} else if (face == 1.0) {
uv = vec2(direction.x, -direction.z) / abs(direction.y);
} else if (face == 2.0) {
uv = direction.xy / abs(direction.z);
} else if (face == 3.0) {
uv = vec2(direction.z, direction.y) / abs(direction.x);
} else if (face == 4.0) {
uv = direction.xz / abs(direction.y);
} else {
uv = vec2(-direction.x, direction.y) / abs(direction.z);
}
return 0.5 * (uv + 1.0);
}
#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)
#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)
vec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {
mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;
float a = 16.0 * cubeUV_rcpTextureSize;
vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );
vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;
// float powScale = exp2(roughnessLevel + mipLevel);
float powScale = exp2_packed.x * exp2_packed.y;
// float scale = 1.0 / exp2(roughnessLevel + 2.0 + mipLevel);
float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;
// float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);
float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;
bool bRes = mipLevel == 0.0;
scale = bRes && (scale < a) ? a : scale;
vec3 r;
vec2 offset;
int face = getFaceFromDirection(direction);
float rcpPowScale = 1.0 / powScale;
if( face == 0) {
r = vec3(direction.x, -direction.z, direction.y);
offset = vec2(0.0+mipOffset,0.75 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;
}
else if( face == 1) {
r = vec3(direction.y, direction.x, direction.z);
offset = vec2(scale+mipOffset, 0.75 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;
}
else if( face == 2) {
r = vec3(direction.z, direction.x, direction.y);
offset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;
}
else if( face == 3) {
r = vec3(direction.x, direction.z, direction.y);
offset = vec2(0.0+mipOffset,0.5 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;
}
else if( face == 4) {
r = vec3(direction.y, direction.x, -direction.z);
offset = vec2(scale+mipOffset, 0.5 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;
}
else {
r = vec3(direction.z, -direction.x, direction.y);
offset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);
offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;
}
r = normalize(r);
float texelOffset = 0.5 * cubeUV_rcpTextureSize;
vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;
vec2 base = offset + vec2( texelOffset );
return base + s * ( scale - 2.0 * texelOffset );
vec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {
float face = getFace(direction);
float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);
mipInt = max(mipInt, cubeUV_minMipLevel);
float faceSize = exp2(mipInt);
float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);
vec2 uv = getUV(direction, face) * (faceSize - 1.0);
vec2 f = fract(uv);
uv += 0.5 - f;
if (face > 2.0) {
uv.y += faceSize;
face -= 3.0;
}
uv.x += face * faceSize;
if(mipInt < cubeUV_maxMipLevel){
uv.y += 2.0 * cubeUV_maxTileSize;
}
uv.y += filterInt * 2.0 * cubeUV_minTileSize;
uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);
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);
}
#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)
vec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {
float roughnessVal = roughness* cubeUV_maxLods3;
float r1 = floor(roughnessVal);
float r2 = r1 + 1.0;
float t = fract(roughnessVal);
vec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);
float s = mipInfo.y;
float level0 = mipInfo.x;
float level1 = level0 + 1.0;
level1 = level1 > 5.0 ? 5.0 : level1;
// round to nearest mipmap if we are not interpolating.
level0 += min( floor( s + 0.5 ), 5.0 );
// Tri linear interpolation.
vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);
vec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));
vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);
vec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));
// These defines must match with PMREMGenerator
#define r0 1.0
#define v0 0.339
#define m0 -2.0
#define r1 0.8
#define v1 0.276
#define m1 -1.0
#define r4 0.4
#define v4 0.046
#define m4 2.0
#define r5 0.305
#define v5 0.016
#define m5 3.0
#define r6 0.21
#define v6 0.0038
#define m6 4.0
float roughnessToVariance(float roughness) {
float variance = 0.0;
if (roughness >= r1) {
variance = (r0 - roughness) * (v1 - v0) / (r0 - r1) + v0;
} else if (roughness >= r4) {
variance = (r1 - roughness) * (v4 - v1) / (r1 - r4) + v1;
} else if (roughness >= r5) {
variance = (r4 - roughness) * (v5 - v4) / (r4 - r5) + v4;
} else {
float roughness2 = roughness * roughness;
variance = 1.79 * roughness2 * roughness2;
}
return variance;
}
vec4 result = mix(color10, color20, t);
float varianceToRoughness(float variance) {
float roughness = 0.0;
if (variance >= v1) {
roughness = (v0 - variance) * (r1 - r0) / (v0 - v1) + r0;
} else if (variance >= v4) {
roughness = (v1 - variance) * (r4 - r1) / (v1 - v4) + r1;
} else if (variance >= v5) {
roughness = (v4 - variance) * (r5 - r4) / (v4 - v5) + r4;
} else {
roughness = pow(0.559 * variance, 0.25);// 0.559 = 1.0 / 1.79
}
return roughness;
}
return vec4(result.rgb, 1.0);
float roughnessToMip(float roughness) {
float mip = 0.0;
if (roughness >= r1) {
mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;
} else if (roughness >= r4) {
mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;
} else if (roughness >= r5) {
mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;
} else if (roughness >= r6) {
mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;
} else {
mip = -2.0 * log2(1.16 * roughness);// 1.16 = 1.79^0.25
}
return mip;
}
vec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {
float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);
float mipF = fract(mip);
float mipInt = floor(mip);
vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);
if (mipF == 0.0) {
return vec4(color0, 1.0);
} else {
vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);
return vec4(mix(color0, color1, mipF), 1.0);
}
}
#endif
`;
......@@ -38,6 +38,10 @@ export default /* glsl */`
vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
#elif defined( ENVMAP_TYPE_CUBE_UV )
vec4 envColor = textureCubeUV( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), 0.0 );
#elif defined( ENVMAP_TYPE_EQUIREC )
vec2 sampleUV;
......@@ -64,7 +68,11 @@ export default /* glsl */`
#endif
envColor = envMapTexelToLinear( envColor );
#ifndef ENVMAP_TYPE_CUBE_UV
envColor = envMapTexelToLinear( envColor );
#endif
#ifdef ENVMAP_BLENDING_MULTIPLY
......
......@@ -236,11 +236,12 @@ var ShaderLib = {
cube: {
uniforms: {
tCube: { value: null },
tFlip: { value: - 1 },
opacity: { value: 1.0 }
},
uniforms: mergeUniforms( [
UniformsLib.envmap,
{
opacity: { value: 1.0 }
}
] ),
vertexShader: ShaderChunk.cube_vert,
fragmentShader: ShaderChunk.cube_frag
......
export default /* glsl */`
uniform samplerCube tCube;
uniform float tFlip;
#include <envmap_common_pars_fragment>
uniform float opacity;
varying vec3 vWorldDirection;
#include <cube_uv_reflection_fragment>
void main() {
vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );
vec3 vReflect = vWorldDirection;
#include <envmap_fragment>
gl_FragColor = mapTexelToLinear( texColor );
gl_FragColor = envColor;
gl_FragColor.a *= opacity;
#include <tonemapping_fragment>
......
......@@ -18,6 +18,7 @@ uniform float opacity;
#include <lightmap_pars_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <fog_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
......
......@@ -25,6 +25,7 @@ varying vec3 vIndirectFront;
#include <emissivemap_pars_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <fog_pars_fragment>
......
......@@ -20,6 +20,7 @@ uniform float opacity;
#include <emissivemap_pars_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
......
......@@ -2,7 +2,7 @@
* @author mrdoob / http://mrdoob.com/
*/
import { BackSide, FrontSide } from '../../constants.js';
import { BackSide, FrontSide, CubeUVReflectionMapping } from '../../constants.js';
import { BoxBufferGeometry } from '../../geometries/BoxGeometry.js';
import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry.js';
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
......@@ -60,7 +60,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
}
if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) {
if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube || background.mapping === CubeUVReflectionMapping ) ) {
if ( boxMesh === undefined ) {
......@@ -92,7 +92,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
get: function () {
return this.uniforms.tCube.value;
return this.envMap.value;
}
......@@ -103,8 +103,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
}
var texture = background.isWebGLRenderTargetCube ? background.texture : background;
boxMesh.material.uniforms.tCube.value = texture;
boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;
boxMesh.material.envMap = texture;
if ( currentBackground !== background ||
currentBackgroundVersion !== texture.version ) {
......
......@@ -351,7 +351,7 @@ function generateEnvMapModeDefine( parameters ) {
function generateEnvMapBlendingDefine( parameters ) {
var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
if ( parameters.envMap ) {
......
......@@ -142,7 +142,6 @@ var files = [
{ path: 'objects/Water.js', dependencies: [], ignoreList: [] },
{ path: 'objects/Water2.js', dependencies: [ { name: 'Reflector', path: 'objects/Reflector.js' }, { name: 'Refractor', path: 'objects/Refractor.js' } ], ignoreList: [] },
{ path: 'pmrem/PMREMCubeUVPacker.js', dependencies: [], ignoreList: [] },
{ path: 'pmrem/PMREMGenerator.js', dependencies: [], ignoreList: [] },
{ path: 'postprocessing/AdaptiveToneMappingPass.js', dependencies: [ { name: 'Pass', path: 'postprocessing/Pass.js' }, { name: 'CopyShader', path: 'shaders/CopyShader.js' }, { name: 'LuminosityShader', path: 'shaders/LuminosityShader.js' }, { name: 'ToneMapShader', path: 'shaders/ToneMapShader.js' } ], ignoreList: [] },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册