Initial commit
This commit is contained in:
346
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/AdaptiveToneMappingPass.js
generated
vendored
Normal file
346
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/AdaptiveToneMappingPass.js
generated
vendored
Normal file
@@ -0,0 +1,346 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
* Generate a texture that represents the luminosity of the current scene, adapted over time
|
||||
* to simulate the optic nerve responding to the amount of light it is receiving.
|
||||
* Based on a GDC2007 presentation by Wolfgang Engel titled "Post-Processing Pipeline"
|
||||
*
|
||||
* Full-screen tone-mapping shader based on http://www.graphics.cornell.edu/~jaf/publications/sig02_paper.pdf
|
||||
*/
|
||||
|
||||
class AdaptiveToneMappingPass extends THREE.Pass {
|
||||
|
||||
constructor( adaptive, resolution ) {
|
||||
|
||||
super();
|
||||
this.resolution = resolution !== undefined ? resolution : 256;
|
||||
this.needsInit = true;
|
||||
this.adaptive = adaptive !== undefined ? !! adaptive : true;
|
||||
this.luminanceRT = null;
|
||||
this.previousLuminanceRT = null;
|
||||
this.currentLuminanceRT = null;
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.AdaptiveToneMappingPass relies on THREE.CopyShader' );
|
||||
const copyShader = THREE.CopyShader;
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
blending: THREE.NoBlending,
|
||||
depthTest: false
|
||||
} );
|
||||
if ( THREE.LuminosityShader === undefined ) console.error( 'THREE.AdaptiveToneMappingPass relies on THREE.LuminosityShader' );
|
||||
this.materialLuminance = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.LuminosityShader.uniforms ),
|
||||
vertexShader: THREE.LuminosityShader.vertexShader,
|
||||
fragmentShader: THREE.LuminosityShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.adaptLuminanceShader = {
|
||||
defines: {
|
||||
'MIP_LEVEL_1X1': ( Math.log( this.resolution ) / Math.log( 2.0 ) ).toFixed( 1 )
|
||||
},
|
||||
uniforms: {
|
||||
'lastLum': {
|
||||
value: null
|
||||
},
|
||||
'currentLum': {
|
||||
value: null
|
||||
},
|
||||
'minLuminance': {
|
||||
value: 0.01
|
||||
},
|
||||
'delta': {
|
||||
value: 0.016
|
||||
},
|
||||
'tau': {
|
||||
value: 1.0
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
|
||||
}`,
|
||||
fragmentShader: `varying vec2 vUv;
|
||||
|
||||
uniform sampler2D lastLum;
|
||||
uniform sampler2D currentLum;
|
||||
uniform float minLuminance;
|
||||
uniform float delta;
|
||||
uniform float tau;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );
|
||||
vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );
|
||||
|
||||
float fLastLum = max( minLuminance, lastLum.r );
|
||||
float fCurrentLum = max( minLuminance, currentLum.r );
|
||||
|
||||
//The adaption seems to work better in extreme lighting differences
|
||||
//if the input luminance is squared.
|
||||
fCurrentLum *= fCurrentLum;
|
||||
|
||||
// Adapt the luminance using Pattanaik's technique
|
||||
float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));
|
||||
// "fAdaptedLum = sqrt(fAdaptedLum);
|
||||
gl_FragColor.r = fAdaptedLum;
|
||||
}`
|
||||
};
|
||||
this.materialAdaptiveLum = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( this.adaptLuminanceShader.uniforms ),
|
||||
vertexShader: this.adaptLuminanceShader.vertexShader,
|
||||
fragmentShader: this.adaptLuminanceShader.fragmentShader,
|
||||
defines: Object.assign( {}, this.adaptLuminanceShader.defines ),
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
if ( THREE.ToneMapShader === undefined ) console.error( 'THREE.AdaptiveToneMappingPass relies on THREE.ToneMapShader' );
|
||||
this.materialToneMap = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.ToneMapShader.uniforms ),
|
||||
vertexShader: THREE.ToneMapShader.vertexShader,
|
||||
fragmentShader: THREE.ToneMapShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime
|
||||
/*, maskActive*/
|
||||
) {
|
||||
|
||||
if ( this.needsInit ) {
|
||||
|
||||
this.reset( renderer );
|
||||
this.luminanceRT.texture.type = readBuffer.texture.type;
|
||||
this.previousLuminanceRT.texture.type = readBuffer.texture.type;
|
||||
this.currentLuminanceRT.texture.type = readBuffer.texture.type;
|
||||
this.needsInit = false;
|
||||
|
||||
}
|
||||
|
||||
if ( this.adaptive ) {
|
||||
|
||||
//Render the luminance of the current scene into a render target with mipmapping enabled
|
||||
this.fsQuad.material = this.materialLuminance;
|
||||
this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture;
|
||||
renderer.setRenderTarget( this.currentLuminanceRT );
|
||||
this.fsQuad.render( renderer ); //Use the new luminance values, the previous luminance and the frame delta to
|
||||
//adapt the luminance over time.
|
||||
|
||||
this.fsQuad.material = this.materialAdaptiveLum;
|
||||
this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
|
||||
this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
|
||||
this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
|
||||
renderer.setRenderTarget( this.luminanceRT );
|
||||
this.fsQuad.render( renderer ); //Copy the new adapted luminance value so that it can be used by the next frame.
|
||||
|
||||
this.fsQuad.material = this.materialCopy;
|
||||
this.copyUniforms.tDiffuse.value = this.luminanceRT.texture;
|
||||
renderer.setRenderTarget( this.previousLuminanceRT );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = this.materialToneMap;
|
||||
this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
||||
// render targets
|
||||
if ( this.luminanceRT ) {
|
||||
|
||||
this.luminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.currentLuminanceRT ) {
|
||||
|
||||
this.currentLuminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.previousLuminanceRT ) {
|
||||
|
||||
this.previousLuminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
const pars = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
}; // was RGB format. changed to RGBA format. see discussion in #8415 / #8450
|
||||
|
||||
this.luminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars );
|
||||
this.luminanceRT.texture.name = 'AdaptiveToneMappingPass.l';
|
||||
this.luminanceRT.texture.generateMipmaps = false;
|
||||
this.previousLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars );
|
||||
this.previousLuminanceRT.texture.name = 'AdaptiveToneMappingPass.pl';
|
||||
this.previousLuminanceRT.texture.generateMipmaps = false; // We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader
|
||||
|
||||
pars.minFilter = THREE.LinearMipmapLinearFilter;
|
||||
pars.generateMipmaps = true;
|
||||
this.currentLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars );
|
||||
this.currentLuminanceRT.texture.name = 'AdaptiveToneMappingPass.cl';
|
||||
|
||||
if ( this.adaptive ) {
|
||||
|
||||
this.materialToneMap.defines[ 'ADAPTED_LUMINANCE' ] = '';
|
||||
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
|
||||
|
||||
} //Put something in the adaptive luminance texture so that the scene can render initially
|
||||
|
||||
|
||||
this.fsQuad.material = new THREE.MeshBasicMaterial( {
|
||||
color: 0x777777
|
||||
} );
|
||||
this.materialLuminance.needsUpdate = true;
|
||||
this.materialAdaptiveLum.needsUpdate = true;
|
||||
this.materialToneMap.needsUpdate = true; // renderer.render( this.scene, this.camera, this.luminanceRT );
|
||||
// renderer.render( this.scene, this.camera, this.previousLuminanceRT );
|
||||
// renderer.render( this.scene, this.camera, this.currentLuminanceRT );
|
||||
|
||||
}
|
||||
|
||||
setAdaptive( adaptive ) {
|
||||
|
||||
if ( adaptive ) {
|
||||
|
||||
this.adaptive = true;
|
||||
this.materialToneMap.defines[ 'ADAPTED_LUMINANCE' ] = '';
|
||||
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
|
||||
|
||||
} else {
|
||||
|
||||
this.adaptive = false;
|
||||
delete this.materialToneMap.defines[ 'ADAPTED_LUMINANCE' ];
|
||||
this.materialToneMap.uniforms.luminanceMap.value = null;
|
||||
|
||||
}
|
||||
|
||||
this.materialToneMap.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
setAdaptionRate( rate ) {
|
||||
|
||||
if ( rate ) {
|
||||
|
||||
this.materialAdaptiveLum.uniforms.tau.value = Math.abs( rate );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setMinLuminance( minLum ) {
|
||||
|
||||
if ( minLum ) {
|
||||
|
||||
this.materialToneMap.uniforms.minLuminance.value = minLum;
|
||||
this.materialAdaptiveLum.uniforms.minLuminance.value = minLum;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setMaxLuminance( maxLum ) {
|
||||
|
||||
if ( maxLum ) {
|
||||
|
||||
this.materialToneMap.uniforms.maxLuminance.value = maxLum;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setAverageLuminance( avgLum ) {
|
||||
|
||||
if ( avgLum ) {
|
||||
|
||||
this.materialToneMap.uniforms.averageLuminance.value = avgLum;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setMiddleGrey( middleGrey ) {
|
||||
|
||||
if ( middleGrey ) {
|
||||
|
||||
this.materialToneMap.uniforms.middleGrey.value = middleGrey;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
if ( this.luminanceRT ) {
|
||||
|
||||
this.luminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.previousLuminanceRT ) {
|
||||
|
||||
this.previousLuminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.currentLuminanceRT ) {
|
||||
|
||||
this.currentLuminanceRT.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.materialLuminance ) {
|
||||
|
||||
this.materialLuminance.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.materialAdaptiveLum ) {
|
||||
|
||||
this.materialAdaptiveLum.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.materialCopy ) {
|
||||
|
||||
this.materialCopy.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.materialToneMap ) {
|
||||
|
||||
this.materialToneMap.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.AdaptiveToneMappingPass = AdaptiveToneMappingPass;
|
||||
|
||||
} )();
|
||||
74
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/AfterimagePass.js
generated
vendored
Normal file
74
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/AfterimagePass.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
( function () {
|
||||
|
||||
class AfterimagePass extends THREE.Pass {
|
||||
|
||||
constructor( damp = 0.96 ) {
|
||||
|
||||
super();
|
||||
if ( THREE.AfterimageShader === undefined ) console.error( 'THREE.AfterimagePass relies on THREE.AfterimageShader' );
|
||||
this.shader = THREE.AfterimageShader;
|
||||
this.uniforms = THREE.UniformsUtils.clone( this.shader.uniforms );
|
||||
this.uniforms[ 'damp' ].value = damp;
|
||||
this.textureComp = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.textureOld = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.shaderMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: this.shader.vertexShader,
|
||||
fragmentShader: this.shader.fragmentShader
|
||||
} );
|
||||
this.compFsQuad = new THREE.FullScreenQuad( this.shaderMaterial );
|
||||
const material = new THREE.MeshBasicMaterial();
|
||||
this.copyFsQuad = new THREE.FullScreenQuad( material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive*/
|
||||
) {
|
||||
|
||||
this.uniforms[ 'tOld' ].value = this.textureOld.texture;
|
||||
this.uniforms[ 'tNew' ].value = readBuffer.texture;
|
||||
renderer.setRenderTarget( this.textureComp );
|
||||
this.compFsQuad.render( renderer );
|
||||
this.copyFsQuad.material.map = this.textureComp.texture;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.copyFsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.copyFsQuad.render( renderer );
|
||||
|
||||
} // Swap buffers.
|
||||
|
||||
|
||||
const temp = this.textureOld;
|
||||
this.textureOld = this.textureComp;
|
||||
this.textureComp = temp; // Now textureOld contains the latest image, ready for the next frame.
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.textureComp.setSize( width, height );
|
||||
this.textureOld.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.AfterimagePass = AfterimagePass;
|
||||
|
||||
} )();
|
||||
83
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/BloomPass.js
generated
vendored
Normal file
83
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/BloomPass.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
( function () {
|
||||
|
||||
class BloomPass extends THREE.Pass {
|
||||
|
||||
constructor( strength = 1, kernelSize = 25, sigma = 4, resolution = 256 ) {
|
||||
|
||||
super(); // render targets
|
||||
|
||||
const pars = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
};
|
||||
this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars );
|
||||
this.renderTargetX.texture.name = 'BloomPass.x';
|
||||
this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars );
|
||||
this.renderTargetY.texture.name = 'BloomPass.y'; // copy material
|
||||
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.BloomPass relies on THREE.CopyShader' );
|
||||
const copyShader = THREE.CopyShader;
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.copyUniforms[ 'opacity' ].value = strength;
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
blending: THREE.AdditiveBlending,
|
||||
transparent: true
|
||||
} ); // convolution material
|
||||
|
||||
if ( THREE.ConvolutionShader === undefined ) console.error( 'THREE.BloomPass relies on THREE.ConvolutionShader' );
|
||||
const convolutionShader = THREE.ConvolutionShader;
|
||||
this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms );
|
||||
this.convolutionUniforms[ 'uImageIncrement' ].value = BloomPass.blurX;
|
||||
this.convolutionUniforms[ 'cKernel' ].value = THREE.ConvolutionShader.buildKernel( sigma );
|
||||
this.materialConvolution = new THREE.ShaderMaterial( {
|
||||
uniforms: this.convolutionUniforms,
|
||||
vertexShader: convolutionShader.vertexShader,
|
||||
fragmentShader: convolutionShader.fragmentShader,
|
||||
defines: {
|
||||
'KERNEL_SIZE_FLOAT': kernelSize.toFixed( 1 ),
|
||||
'KERNEL_SIZE_INT': kernelSize.toFixed( 0 )
|
||||
}
|
||||
} );
|
||||
this.needsSwap = false;
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
|
||||
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); // Render quad with blured scene into texture (convolution pass 1)
|
||||
|
||||
this.fsQuad.material = this.materialConvolution;
|
||||
this.convolutionUniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.convolutionUniforms[ 'uImageIncrement' ].value = BloomPass.blurX;
|
||||
renderer.setRenderTarget( this.renderTargetX );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // Render quad with blured scene into texture (convolution pass 2)
|
||||
|
||||
this.convolutionUniforms[ 'tDiffuse' ].value = this.renderTargetX.texture;
|
||||
this.convolutionUniforms[ 'uImageIncrement' ].value = BloomPass.blurY;
|
||||
renderer.setRenderTarget( this.renderTargetY );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // Render original scene with superimposed blur to texture
|
||||
|
||||
this.fsQuad.material = this.materialCopy;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetY.texture;
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
|
||||
renderer.setRenderTarget( readBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 );
|
||||
BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 );
|
||||
|
||||
THREE.BloomPass = BloomPass;
|
||||
|
||||
} )();
|
||||
103
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/BokehPass.js
generated
vendored
Normal file
103
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/BokehPass.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
* Depth-of-field post-process with bokeh shader
|
||||
*/
|
||||
|
||||
class BokehPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera, params ) {
|
||||
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
const focus = params.focus !== undefined ? params.focus : 1.0;
|
||||
const aspect = params.aspect !== undefined ? params.aspect : camera.aspect;
|
||||
const aperture = params.aperture !== undefined ? params.aperture : 0.025;
|
||||
const maxblur = params.maxblur !== undefined ? params.maxblur : 1.0; // render targets
|
||||
|
||||
const width = params.width || window.innerWidth || 1;
|
||||
const height = params.height || window.innerHeight || 1;
|
||||
this.renderTargetDepth = new THREE.WebGLRenderTarget( width, height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter
|
||||
} );
|
||||
this.renderTargetDepth.texture.name = 'BokehPass.depth'; // depth material
|
||||
|
||||
this.materialDepth = new THREE.MeshDepthMaterial();
|
||||
this.materialDepth.depthPacking = THREE.RGBADepthPacking;
|
||||
this.materialDepth.blending = THREE.NoBlending; // bokeh material
|
||||
|
||||
if ( THREE.BokehShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.BokehPass relies on THREE.BokehShader' );
|
||||
|
||||
}
|
||||
|
||||
const bokehShader = THREE.BokehShader;
|
||||
const bokehUniforms = THREE.UniformsUtils.clone( bokehShader.uniforms );
|
||||
bokehUniforms[ 'tDepth' ].value = this.renderTargetDepth.texture;
|
||||
bokehUniforms[ 'focus' ].value = focus;
|
||||
bokehUniforms[ 'aspect' ].value = aspect;
|
||||
bokehUniforms[ 'aperture' ].value = aperture;
|
||||
bokehUniforms[ 'maxblur' ].value = maxblur;
|
||||
bokehUniforms[ 'nearClip' ].value = camera.near;
|
||||
bokehUniforms[ 'farClip' ].value = camera.far;
|
||||
this.materialBokeh = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, bokehShader.defines ),
|
||||
uniforms: bokehUniforms,
|
||||
vertexShader: bokehShader.vertexShader,
|
||||
fragmentShader: bokehShader.fragmentShader
|
||||
} );
|
||||
this.uniforms = bokehUniforms;
|
||||
this.needsSwap = false;
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.materialBokeh );
|
||||
this._oldClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive*/
|
||||
) {
|
||||
|
||||
// Render depth into texture
|
||||
this.scene.overrideMaterial = this.materialDepth;
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
const oldClearAlpha = renderer.getClearAlpha();
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
renderer.setClearColor( 0xffffff );
|
||||
renderer.setClearAlpha( 1.0 );
|
||||
renderer.setRenderTarget( this.renderTargetDepth );
|
||||
renderer.clear();
|
||||
renderer.render( this.scene, this.camera ); // Render bokeh composite
|
||||
|
||||
this.uniforms[ 'tColor' ].value = readBuffer.texture;
|
||||
this.uniforms[ 'nearClip' ].value = this.camera.near;
|
||||
this.uniforms[ 'farClip' ].value = this.camera.far;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = null;
|
||||
renderer.setClearColor( this._oldClearColor );
|
||||
renderer.setClearAlpha( oldClearAlpha );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.BokehPass = BokehPass;
|
||||
|
||||
} )();
|
||||
44
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/ClearPass.js
generated
vendored
Normal file
44
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/ClearPass.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
( function () {
|
||||
|
||||
class ClearPass extends THREE.Pass {
|
||||
|
||||
constructor( clearColor, clearAlpha ) {
|
||||
|
||||
super();
|
||||
this.needsSwap = false;
|
||||
this.clearColor = clearColor !== undefined ? clearColor : 0x000000;
|
||||
this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0;
|
||||
this._oldClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
let oldClearAlpha;
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
oldClearAlpha = renderer.getClearAlpha();
|
||||
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
|
||||
renderer.clear();
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
renderer.setClearColor( this._oldClearColor, oldClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.ClearPass = ClearPass;
|
||||
|
||||
} )();
|
||||
57
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/CubeTexturePass.js
generated
vendored
Normal file
57
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/CubeTexturePass.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
( function () {
|
||||
|
||||
class CubeTexturePass extends THREE.Pass {
|
||||
|
||||
constructor( camera, envMap, opacity = 1 ) {
|
||||
|
||||
super();
|
||||
this.camera = camera;
|
||||
this.needsSwap = false;
|
||||
this.cubeShader = THREE.ShaderLib[ 'cube' ];
|
||||
this.cubeMesh = new THREE.Mesh( new THREE.BoxGeometry( 10, 10, 10 ), new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( this.cubeShader.uniforms ),
|
||||
vertexShader: this.cubeShader.vertexShader,
|
||||
fragmentShader: this.cubeShader.fragmentShader,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
side: THREE.BackSide
|
||||
} ) );
|
||||
Object.defineProperty( this.cubeMesh.material, 'envMap', {
|
||||
get: function () {
|
||||
|
||||
return this.uniforms.envMap.value;
|
||||
|
||||
}
|
||||
} );
|
||||
this.envMap = envMap;
|
||||
this.opacity = opacity;
|
||||
this.cubeScene = new THREE.Scene();
|
||||
this.cubeCamera = new THREE.PerspectiveCamera();
|
||||
this.cubeScene.add( this.cubeMesh );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive*/
|
||||
) {
|
||||
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
this.cubeCamera.projectionMatrix.copy( this.camera.projectionMatrix );
|
||||
this.cubeCamera.quaternion.setFromRotationMatrix( this.camera.matrixWorld );
|
||||
this.cubeMesh.material.uniforms.envMap.value = this.envMap;
|
||||
this.cubeMesh.material.uniforms.flipEnvMap.value = this.envMap.isCubeTexture && this.envMap.isRenderTargetTexture === false ? - 1 : 1;
|
||||
this.cubeMesh.material.uniforms.opacity.value = this.opacity;
|
||||
this.cubeMesh.material.transparent = this.opacity < 1.0;
|
||||
renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
renderer.render( this.cubeScene, this.cubeCamera );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.CubeTexturePass = CubeTexturePass;
|
||||
|
||||
} )();
|
||||
49
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/DotScreenPass.js
generated
vendored
Normal file
49
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/DotScreenPass.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
( function () {
|
||||
|
||||
class DotScreenPass extends THREE.Pass {
|
||||
|
||||
constructor( center, angle, scale ) {
|
||||
|
||||
super();
|
||||
if ( THREE.DotScreenShader === undefined ) console.error( 'THREE.DotScreenPass relies on THREE.DotScreenShader' );
|
||||
const shader = THREE.DotScreenShader;
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
if ( center !== undefined ) this.uniforms[ 'center' ].value.copy( center );
|
||||
if ( angle !== undefined ) this.uniforms[ 'angle' ].value = angle;
|
||||
if ( scale !== undefined ) this.uniforms[ 'scale' ].value = scale;
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.uniforms[ 'tSize' ].value.set( readBuffer.width, readBuffer.height );
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.DotScreenPass = DotScreenPass;
|
||||
|
||||
} )();
|
||||
284
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/EffectComposer.js
generated
vendored
Normal file
284
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/EffectComposer.js
generated
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
( function () {
|
||||
|
||||
class EffectComposer {
|
||||
|
||||
constructor( renderer, renderTarget ) {
|
||||
|
||||
this.renderer = renderer;
|
||||
|
||||
if ( renderTarget === undefined ) {
|
||||
|
||||
const parameters = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
};
|
||||
const size = renderer.getSize( new THREE.Vector2() );
|
||||
this._pixelRatio = renderer.getPixelRatio();
|
||||
this._width = size.width;
|
||||
this._height = size.height;
|
||||
renderTarget = new THREE.WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, parameters );
|
||||
renderTarget.texture.name = 'EffectComposer.rt1';
|
||||
|
||||
} else {
|
||||
|
||||
this._pixelRatio = 1;
|
||||
this._width = renderTarget.width;
|
||||
this._height = renderTarget.height;
|
||||
|
||||
}
|
||||
|
||||
this.renderTarget1 = renderTarget;
|
||||
this.renderTarget2 = renderTarget.clone();
|
||||
this.renderTarget2.texture.name = 'EffectComposer.rt2';
|
||||
this.writeBuffer = this.renderTarget1;
|
||||
this.readBuffer = this.renderTarget2;
|
||||
this.renderToScreen = true;
|
||||
this.passes = []; // dependencies
|
||||
|
||||
if ( THREE.CopyShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );
|
||||
|
||||
}
|
||||
|
||||
if ( THREE.ShaderPass === undefined ) {
|
||||
|
||||
console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );
|
||||
|
||||
}
|
||||
|
||||
this.copyPass = new THREE.ShaderPass( THREE.CopyShader );
|
||||
this.clock = new THREE.Clock();
|
||||
|
||||
}
|
||||
|
||||
swapBuffers() {
|
||||
|
||||
const tmp = this.readBuffer;
|
||||
this.readBuffer = this.writeBuffer;
|
||||
this.writeBuffer = tmp;
|
||||
|
||||
}
|
||||
|
||||
addPass( pass ) {
|
||||
|
||||
this.passes.push( pass );
|
||||
pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
|
||||
|
||||
}
|
||||
|
||||
insertPass( pass, index ) {
|
||||
|
||||
this.passes.splice( index, 0, pass );
|
||||
pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
|
||||
|
||||
}
|
||||
|
||||
removePass( pass ) {
|
||||
|
||||
const index = this.passes.indexOf( pass );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
this.passes.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isLastEnabledPass( passIndex ) {
|
||||
|
||||
for ( let i = passIndex + 1; i < this.passes.length; i ++ ) {
|
||||
|
||||
if ( this.passes[ i ].enabled ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
render( deltaTime ) {
|
||||
|
||||
// deltaTime value is in seconds
|
||||
if ( deltaTime === undefined ) {
|
||||
|
||||
deltaTime = this.clock.getDelta();
|
||||
|
||||
}
|
||||
|
||||
const currentRenderTarget = this.renderer.getRenderTarget();
|
||||
let maskActive = false;
|
||||
|
||||
for ( let i = 0, il = this.passes.length; i < il; i ++ ) {
|
||||
|
||||
const pass = this.passes[ i ];
|
||||
if ( pass.enabled === false ) continue;
|
||||
pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass( i );
|
||||
pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );
|
||||
|
||||
if ( pass.needsSwap ) {
|
||||
|
||||
if ( maskActive ) {
|
||||
|
||||
const context = this.renderer.getContext();
|
||||
const stencil = this.renderer.state.buffers.stencil; //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
|
||||
|
||||
stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );
|
||||
this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime ); //context.stencilFunc( context.EQUAL, 1, 0xffffffff );
|
||||
|
||||
stencil.setFunc( context.EQUAL, 1, 0xffffffff );
|
||||
|
||||
}
|
||||
|
||||
this.swapBuffers();
|
||||
|
||||
}
|
||||
|
||||
if ( THREE.MaskPass !== undefined ) {
|
||||
|
||||
if ( pass instanceof THREE.MaskPass ) {
|
||||
|
||||
maskActive = true;
|
||||
|
||||
} else if ( pass instanceof THREE.ClearMaskPass ) {
|
||||
|
||||
maskActive = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.renderer.setRenderTarget( currentRenderTarget );
|
||||
|
||||
}
|
||||
|
||||
reset( renderTarget ) {
|
||||
|
||||
if ( renderTarget === undefined ) {
|
||||
|
||||
const size = this.renderer.getSize( new THREE.Vector2() );
|
||||
this._pixelRatio = this.renderer.getPixelRatio();
|
||||
this._width = size.width;
|
||||
this._height = size.height;
|
||||
renderTarget = this.renderTarget1.clone();
|
||||
renderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
|
||||
|
||||
}
|
||||
|
||||
this.renderTarget1.dispose();
|
||||
this.renderTarget2.dispose();
|
||||
this.renderTarget1 = renderTarget;
|
||||
this.renderTarget2 = renderTarget.clone();
|
||||
this.writeBuffer = this.renderTarget1;
|
||||
this.readBuffer = this.renderTarget2;
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
const effectiveWidth = this._width * this._pixelRatio;
|
||||
const effectiveHeight = this._height * this._pixelRatio;
|
||||
this.renderTarget1.setSize( effectiveWidth, effectiveHeight );
|
||||
this.renderTarget2.setSize( effectiveWidth, effectiveHeight );
|
||||
|
||||
for ( let i = 0; i < this.passes.length; i ++ ) {
|
||||
|
||||
this.passes[ i ].setSize( effectiveWidth, effectiveHeight );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setPixelRatio( pixelRatio ) {
|
||||
|
||||
this._pixelRatio = pixelRatio;
|
||||
this.setSize( this._width, this._height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Pass {
|
||||
|
||||
constructor() {
|
||||
|
||||
// if set to true, the pass is processed by the composer
|
||||
this.enabled = true; // if set to true, the pass indicates to swap read and write buffer after rendering
|
||||
|
||||
this.needsSwap = true; // if set to true, the pass clears its buffer before rendering
|
||||
|
||||
this.clear = false; // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
|
||||
|
||||
this.renderToScreen = false;
|
||||
|
||||
}
|
||||
|
||||
setSize() {}
|
||||
|
||||
render() {
|
||||
|
||||
console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
|
||||
|
||||
}
|
||||
|
||||
} // Helper for passes that need to fill the viewport with a single quad.
|
||||
|
||||
|
||||
const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); // https://github.com/mrdoob/three.js/pull/21358
|
||||
|
||||
|
||||
const _geometry = new THREE.BufferGeometry();
|
||||
|
||||
_geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
|
||||
|
||||
_geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
|
||||
|
||||
class FullScreenQuad {
|
||||
|
||||
constructor( material ) {
|
||||
|
||||
this._mesh = new THREE.Mesh( _geometry, material );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this._mesh.geometry.dispose();
|
||||
|
||||
}
|
||||
|
||||
render( renderer ) {
|
||||
|
||||
renderer.render( this._mesh, _camera );
|
||||
|
||||
}
|
||||
|
||||
get material() {
|
||||
|
||||
return this._mesh.material;
|
||||
|
||||
}
|
||||
|
||||
set material( value ) {
|
||||
|
||||
this._mesh.material = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.EffectComposer = EffectComposer;
|
||||
THREE.FullScreenQuad = FullScreenQuad;
|
||||
THREE.Pass = Pass;
|
||||
|
||||
} )();
|
||||
50
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/FilmPass.js
generated
vendored
Normal file
50
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/FilmPass.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
( function () {
|
||||
|
||||
class FilmPass extends THREE.Pass {
|
||||
|
||||
constructor( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) {
|
||||
|
||||
super();
|
||||
if ( THREE.FilmShader === undefined ) console.error( 'THREE.FilmPass relies on THREE.FilmShader' );
|
||||
const shader = THREE.FilmShader;
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
} );
|
||||
if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale;
|
||||
if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity;
|
||||
if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity;
|
||||
if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount;
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime
|
||||
/*, maskActive */
|
||||
) {
|
||||
|
||||
this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.uniforms[ 'time' ].value += deltaTime;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.FilmPass = FilmPass;
|
||||
|
||||
} )();
|
||||
105
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/GlitchPass.js
generated
vendored
Normal file
105
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/GlitchPass.js
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
( function () {
|
||||
|
||||
class GlitchPass extends THREE.Pass {
|
||||
|
||||
constructor( dt_size = 64 ) {
|
||||
|
||||
super();
|
||||
if ( THREE.DigitalGlitch === undefined ) console.error( 'THREE.GlitchPass relies on THREE.DigitalGlitch' );
|
||||
const shader = THREE.DigitalGlitch;
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
this.uniforms[ 'tDisp' ].value = this.generateHeightmap( dt_size );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
this.goWild = false;
|
||||
this.curF = 0;
|
||||
this.generateTrigger();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
if ( renderer.capabilities.isWebGL2 === false ) this.uniforms[ 'tDisp' ].value.format = THREE.LuminanceFormat;
|
||||
this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.uniforms[ 'seed' ].value = Math.random(); //default seeding
|
||||
|
||||
this.uniforms[ 'byp' ].value = 0;
|
||||
|
||||
if ( this.curF % this.randX == 0 || this.goWild == true ) {
|
||||
|
||||
this.uniforms[ 'amount' ].value = Math.random() / 30;
|
||||
this.uniforms[ 'angle' ].value = THREE.MathUtils.randFloat( - Math.PI, Math.PI );
|
||||
this.uniforms[ 'seed_x' ].value = THREE.MathUtils.randFloat( - 1, 1 );
|
||||
this.uniforms[ 'seed_y' ].value = THREE.MathUtils.randFloat( - 1, 1 );
|
||||
this.uniforms[ 'distortion_x' ].value = THREE.MathUtils.randFloat( 0, 1 );
|
||||
this.uniforms[ 'distortion_y' ].value = THREE.MathUtils.randFloat( 0, 1 );
|
||||
this.curF = 0;
|
||||
this.generateTrigger();
|
||||
|
||||
} else if ( this.curF % this.randX < this.randX / 5 ) {
|
||||
|
||||
this.uniforms[ 'amount' ].value = Math.random() / 90;
|
||||
this.uniforms[ 'angle' ].value = THREE.MathUtils.randFloat( - Math.PI, Math.PI );
|
||||
this.uniforms[ 'distortion_x' ].value = THREE.MathUtils.randFloat( 0, 1 );
|
||||
this.uniforms[ 'distortion_y' ].value = THREE.MathUtils.randFloat( 0, 1 );
|
||||
this.uniforms[ 'seed_x' ].value = THREE.MathUtils.randFloat( - 0.3, 0.3 );
|
||||
this.uniforms[ 'seed_y' ].value = THREE.MathUtils.randFloat( - 0.3, 0.3 );
|
||||
|
||||
} else if ( this.goWild == false ) {
|
||||
|
||||
this.uniforms[ 'byp' ].value = 1;
|
||||
|
||||
}
|
||||
|
||||
this.curF ++;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generateTrigger() {
|
||||
|
||||
this.randX = THREE.MathUtils.randInt( 120, 240 );
|
||||
|
||||
}
|
||||
|
||||
generateHeightmap( dt_size ) {
|
||||
|
||||
const data_arr = new Float32Array( dt_size * dt_size );
|
||||
const length = dt_size * dt_size;
|
||||
|
||||
for ( let i = 0; i < length; i ++ ) {
|
||||
|
||||
const val = THREE.MathUtils.randFloat( 0, 1 );
|
||||
data_arr[ i ] = val;
|
||||
|
||||
}
|
||||
|
||||
const texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RedFormat, THREE.FloatType );
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.GlitchPass = GlitchPass;
|
||||
|
||||
} )();
|
||||
75
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/HalftonePass.js
generated
vendored
Normal file
75
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/HalftonePass.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
* RGB Halftone pass for three.js effects composer. Requires THREE.HalftoneShader.
|
||||
*/
|
||||
|
||||
class HalftonePass extends THREE.Pass {
|
||||
|
||||
constructor( width, height, params ) {
|
||||
|
||||
super();
|
||||
|
||||
if ( THREE.HalftoneShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.HalftonePass requires THREE.HalftoneShader' );
|
||||
|
||||
}
|
||||
|
||||
this.uniforms = THREE.UniformsUtils.clone( THREE.HalftoneShader.uniforms );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
fragmentShader: THREE.HalftoneShader.fragmentShader,
|
||||
vertexShader: THREE.HalftoneShader.vertexShader
|
||||
} ); // set params
|
||||
|
||||
this.uniforms.width.value = width;
|
||||
this.uniforms.height.value = height;
|
||||
|
||||
for ( const key in params ) {
|
||||
|
||||
if ( params.hasOwnProperty( key ) && this.uniforms.hasOwnProperty( key ) ) {
|
||||
|
||||
this.uniforms[ key ].value = params[ key ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive*/
|
||||
) {
|
||||
|
||||
this.material.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.uniforms.width.value = width;
|
||||
this.uniforms.height.value = height;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.HalftonePass = HalftonePass;
|
||||
|
||||
} )();
|
||||
184
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/LUTPass.js
generated
vendored
Normal file
184
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/LUTPass.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
( function () {
|
||||
|
||||
const LUTShader = {
|
||||
defines: {
|
||||
USE_3DTEXTURE: 1
|
||||
},
|
||||
uniforms: {
|
||||
lut3d: {
|
||||
value: null
|
||||
},
|
||||
lut: {
|
||||
value: null
|
||||
},
|
||||
lutSize: {
|
||||
value: 0
|
||||
},
|
||||
tDiffuse: {
|
||||
value: null
|
||||
},
|
||||
intensity: {
|
||||
value: 1.0
|
||||
}
|
||||
},
|
||||
vertexShader:
|
||||
/* glsl */
|
||||
`
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
|
||||
}
|
||||
|
||||
`,
|
||||
fragmentShader:
|
||||
/* glsl */
|
||||
`
|
||||
|
||||
uniform float lutSize;
|
||||
#if USE_3DTEXTURE
|
||||
precision highp sampler3D;
|
||||
uniform sampler3D lut3d;
|
||||
#else
|
||||
uniform sampler2D lut;
|
||||
|
||||
vec3 lutLookup( sampler2D tex, float size, vec3 rgb ) {
|
||||
|
||||
float sliceHeight = 1.0 / size;
|
||||
float yPixelHeight = 1.0 / ( size * size );
|
||||
|
||||
// Get the slices on either side of the sample
|
||||
float slice = rgb.b * size;
|
||||
float interp = fract( slice );
|
||||
float slice0 = slice - interp;
|
||||
float centeredInterp = interp - 0.5;
|
||||
|
||||
float slice1 = slice0 + sign( centeredInterp );
|
||||
|
||||
// Pull y sample in by half a pixel in each direction to avoid color
|
||||
// bleeding from adjacent slices.
|
||||
float greenOffset = clamp( rgb.g * sliceHeight, yPixelHeight * 0.5, sliceHeight - yPixelHeight * 0.5 );
|
||||
|
||||
vec2 uv0 = vec2(
|
||||
rgb.r,
|
||||
slice0 * sliceHeight + greenOffset
|
||||
);
|
||||
vec2 uv1 = vec2(
|
||||
rgb.r,
|
||||
slice1 * sliceHeight + greenOffset
|
||||
);
|
||||
|
||||
vec3 sample0 = texture2D( tex, uv0 ).rgb;
|
||||
vec3 sample1 = texture2D( tex, uv1 ).rgb;
|
||||
|
||||
return mix( sample0, sample1, abs( centeredInterp ) );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
varying vec2 vUv;
|
||||
uniform float intensity;
|
||||
uniform sampler2D tDiffuse;
|
||||
void main() {
|
||||
|
||||
vec4 val = texture2D( tDiffuse, vUv );
|
||||
vec4 lutVal;
|
||||
|
||||
// pull the sample in by half a pixel so the sample begins
|
||||
// at the center of the edge pixels.
|
||||
float pixelWidth = 1.0 / lutSize;
|
||||
float halfPixelWidth = 0.5 / lutSize;
|
||||
vec3 uvw = vec3( halfPixelWidth ) + val.rgb * ( 1.0 - pixelWidth );
|
||||
|
||||
#if USE_3DTEXTURE
|
||||
|
||||
lutVal = vec4( texture( lut3d, uvw ).rgb, val.a );
|
||||
|
||||
#else
|
||||
|
||||
lutVal = vec4( lutLookup( lut, lutSize, uvw ), val.a );
|
||||
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4( mix( val, lutVal, intensity ) );
|
||||
|
||||
}
|
||||
|
||||
`
|
||||
};
|
||||
|
||||
class LUTPass extends THREE.ShaderPass {
|
||||
|
||||
set lut( v ) {
|
||||
|
||||
const material = this.material;
|
||||
|
||||
if ( v !== this.lut ) {
|
||||
|
||||
material.uniforms.lut3d.value = null;
|
||||
material.uniforms.lut.value = null;
|
||||
|
||||
if ( v ) {
|
||||
|
||||
const is3dTextureDefine = v.isData3DTexture ? 1 : 0;
|
||||
|
||||
if ( is3dTextureDefine !== material.defines.USE_3DTEXTURE ) {
|
||||
|
||||
material.defines.USE_3DTEXTURE = is3dTextureDefine;
|
||||
material.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
material.uniforms.lutSize.value = v.image.width;
|
||||
|
||||
if ( v.isData3DTexture ) {
|
||||
|
||||
material.uniforms.lut3d.value = v;
|
||||
|
||||
} else {
|
||||
|
||||
material.uniforms.lut.value = v;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get lut() {
|
||||
|
||||
return this.material.uniforms.lut.value || this.material.uniforms.lut3d.value;
|
||||
|
||||
}
|
||||
|
||||
set intensity( v ) {
|
||||
|
||||
this.material.uniforms.intensity.value = v;
|
||||
|
||||
}
|
||||
|
||||
get intensity() {
|
||||
|
||||
return this.material.uniforms.intensity.value;
|
||||
|
||||
}
|
||||
|
||||
constructor( options = {} ) {
|
||||
|
||||
super( LUTShader );
|
||||
this.lut = options.lut || null;
|
||||
this.intensity = 'intensity' in options ? options.intensity : 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.LUTPass = LUTPass;
|
||||
|
||||
} )();
|
||||
92
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/MaskPass.js
generated
vendored
Normal file
92
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/MaskPass.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
( function () {
|
||||
|
||||
class MaskPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera ) {
|
||||
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.clear = true;
|
||||
this.needsSwap = false;
|
||||
this.inverse = false;
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
const context = renderer.getContext();
|
||||
const state = renderer.state; // don't update color or depth
|
||||
|
||||
state.buffers.color.setMask( false );
|
||||
state.buffers.depth.setMask( false ); // lock buffers
|
||||
|
||||
state.buffers.color.setLocked( true );
|
||||
state.buffers.depth.setLocked( true ); // set up stencil
|
||||
|
||||
let writeValue, clearValue;
|
||||
|
||||
if ( this.inverse ) {
|
||||
|
||||
writeValue = 0;
|
||||
clearValue = 1;
|
||||
|
||||
} else {
|
||||
|
||||
writeValue = 1;
|
||||
clearValue = 0;
|
||||
|
||||
}
|
||||
|
||||
state.buffers.stencil.setTest( true );
|
||||
state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE );
|
||||
state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff );
|
||||
state.buffers.stencil.setClear( clearValue );
|
||||
state.buffers.stencil.setLocked( true ); // draw into the stencil buffer
|
||||
|
||||
renderer.setRenderTarget( readBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
renderer.render( this.scene, this.camera );
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
renderer.render( this.scene, this.camera ); // unlock color and depth buffer for subsequent rendering
|
||||
|
||||
state.buffers.color.setLocked( false );
|
||||
state.buffers.depth.setLocked( false ); // only render where stencil is set to 1
|
||||
|
||||
state.buffers.stencil.setLocked( false );
|
||||
state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
|
||||
|
||||
state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP );
|
||||
state.buffers.stencil.setLocked( true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ClearMaskPass extends THREE.Pass {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this.needsSwap = false;
|
||||
|
||||
}
|
||||
|
||||
render( renderer
|
||||
/*, writeBuffer, readBuffer, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
renderer.state.buffers.stencil.setLocked( false );
|
||||
renderer.state.buffers.stencil.setTest( false );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.ClearMaskPass = ClearMaskPass;
|
||||
THREE.MaskPass = MaskPass;
|
||||
|
||||
} )();
|
||||
592
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/OutlinePass.js
generated
vendored
Normal file
592
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/OutlinePass.js
generated
vendored
Normal file
@@ -0,0 +1,592 @@
|
||||
( function () {
|
||||
|
||||
class OutlinePass extends THREE.Pass {
|
||||
|
||||
constructor( resolution, scene, camera, selectedObjects ) {
|
||||
|
||||
super();
|
||||
this.renderScene = scene;
|
||||
this.renderCamera = camera;
|
||||
this.selectedObjects = selectedObjects !== undefined ? selectedObjects : [];
|
||||
this.visibleEdgeColor = new THREE.Color( 1, 1, 1 );
|
||||
this.hiddenEdgeColor = new THREE.Color( 0.1, 0.04, 0.02 );
|
||||
this.edgeGlow = 0.0;
|
||||
this.usePatternTexture = false;
|
||||
this.edgeThickness = 1.0;
|
||||
this.edgeStrength = 3.0;
|
||||
this.downSampleRatio = 2;
|
||||
this.pulsePeriod = 0;
|
||||
this._visibilityCache = new Map();
|
||||
this.resolution = resolution !== undefined ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 );
|
||||
const pars = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
};
|
||||
const resx = Math.round( this.resolution.x / this.downSampleRatio );
|
||||
const resy = Math.round( this.resolution.y / this.downSampleRatio );
|
||||
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
||||
this.renderTargetMaskBuffer.texture.name = 'OutlinePass.mask';
|
||||
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
|
||||
this.depthMaterial = new THREE.MeshDepthMaterial();
|
||||
this.depthMaterial.side = THREE.DoubleSide;
|
||||
this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
|
||||
this.depthMaterial.blending = THREE.NoBlending;
|
||||
this.prepareMaskMaterial = this.getPrepareMaskMaterial();
|
||||
this.prepareMaskMaterial.side = THREE.DoubleSide;
|
||||
this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ( this.prepareMaskMaterial.fragmentShader, this.renderCamera );
|
||||
this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
||||
this.renderTargetDepthBuffer.texture.name = 'OutlinePass.depth';
|
||||
this.renderTargetDepthBuffer.texture.generateMipmaps = false;
|
||||
this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetMaskDownSampleBuffer.texture.name = 'OutlinePass.depthDownSample';
|
||||
this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;
|
||||
this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetBlurBuffer1.texture.name = 'OutlinePass.blur1';
|
||||
this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
|
||||
this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
||||
this.renderTargetBlurBuffer2.texture.name = 'OutlinePass.blur2';
|
||||
this.renderTargetBlurBuffer2.texture.generateMipmaps = false;
|
||||
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial();
|
||||
this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetEdgeBuffer1.texture.name = 'OutlinePass.edge1';
|
||||
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
|
||||
this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
||||
this.renderTargetEdgeBuffer2.texture.name = 'OutlinePass.edge2';
|
||||
this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;
|
||||
const MAX_EDGE_THICKNESS = 4;
|
||||
const MAX_EDGE_GLOW = 4;
|
||||
this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS );
|
||||
this.separableBlurMaterial1.uniforms[ 'texSize' ].value.set( resx, resy );
|
||||
this.separableBlurMaterial1.uniforms[ 'kernelRadius' ].value = 1;
|
||||
this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW );
|
||||
this.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( Math.round( resx / 2 ), Math.round( resy / 2 ) );
|
||||
this.separableBlurMaterial2.uniforms[ 'kernelRadius' ].value = MAX_EDGE_GLOW; // Overlay material
|
||||
|
||||
this.overlayMaterial = this.getOverlayMaterial(); // copy material
|
||||
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.OutlinePass relies on THREE.CopyShader' );
|
||||
const copyShader = THREE.CopyShader;
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.copyUniforms[ 'opacity' ].value = 1.0;
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
blending: THREE.NoBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
transparent: true
|
||||
} );
|
||||
this.enabled = true;
|
||||
this.needsSwap = false;
|
||||
this._oldClearColor = new THREE.Color();
|
||||
this.oldClearAlpha = 1;
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
this.tempPulseColor1 = new THREE.Color();
|
||||
this.tempPulseColor2 = new THREE.Color();
|
||||
this.textureMatrix = new THREE.Matrix4();
|
||||
|
||||
function replaceDepthToViewZ( string, camera ) {
|
||||
|
||||
const type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';
|
||||
return string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.renderTargetMaskBuffer.dispose();
|
||||
this.renderTargetDepthBuffer.dispose();
|
||||
this.renderTargetMaskDownSampleBuffer.dispose();
|
||||
this.renderTargetBlurBuffer1.dispose();
|
||||
this.renderTargetBlurBuffer2.dispose();
|
||||
this.renderTargetEdgeBuffer1.dispose();
|
||||
this.renderTargetEdgeBuffer2.dispose();
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.renderTargetMaskBuffer.setSize( width, height );
|
||||
this.renderTargetDepthBuffer.setSize( width, height );
|
||||
let resx = Math.round( width / this.downSampleRatio );
|
||||
let resy = Math.round( height / this.downSampleRatio );
|
||||
this.renderTargetMaskDownSampleBuffer.setSize( resx, resy );
|
||||
this.renderTargetBlurBuffer1.setSize( resx, resy );
|
||||
this.renderTargetEdgeBuffer1.setSize( resx, resy );
|
||||
this.separableBlurMaterial1.uniforms[ 'texSize' ].value.set( resx, resy );
|
||||
resx = Math.round( resx / 2 );
|
||||
resy = Math.round( resy / 2 );
|
||||
this.renderTargetBlurBuffer2.setSize( resx, resy );
|
||||
this.renderTargetEdgeBuffer2.setSize( resx, resy );
|
||||
this.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( resx, resy );
|
||||
|
||||
}
|
||||
|
||||
changeVisibilityOfSelectedObjects( bVisible ) {
|
||||
|
||||
const cache = this._visibilityCache;
|
||||
|
||||
function gatherSelectedMeshesCallBack( object ) {
|
||||
|
||||
if ( object.isMesh ) {
|
||||
|
||||
if ( bVisible === true ) {
|
||||
|
||||
object.visible = cache.get( object );
|
||||
|
||||
} else {
|
||||
|
||||
cache.set( object, object.visible );
|
||||
object.visible = bVisible;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < this.selectedObjects.length; i ++ ) {
|
||||
|
||||
const selectedObject = this.selectedObjects[ i ];
|
||||
selectedObject.traverse( gatherSelectedMeshesCallBack );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
changeVisibilityOfNonSelectedObjects( bVisible ) {
|
||||
|
||||
const cache = this._visibilityCache;
|
||||
const selectedMeshes = [];
|
||||
|
||||
function gatherSelectedMeshesCallBack( object ) {
|
||||
|
||||
if ( object.isMesh ) selectedMeshes.push( object );
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < this.selectedObjects.length; i ++ ) {
|
||||
|
||||
const selectedObject = this.selectedObjects[ i ];
|
||||
selectedObject.traverse( gatherSelectedMeshesCallBack );
|
||||
|
||||
}
|
||||
|
||||
function VisibilityChangeCallBack( object ) {
|
||||
|
||||
if ( object.isMesh || object.isSprite ) {
|
||||
|
||||
// only meshes and sprites are supported by OutlinePass
|
||||
let bFound = false;
|
||||
|
||||
for ( let i = 0; i < selectedMeshes.length; i ++ ) {
|
||||
|
||||
const selectedObjectId = selectedMeshes[ i ].id;
|
||||
|
||||
if ( selectedObjectId === object.id ) {
|
||||
|
||||
bFound = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( bFound === false ) {
|
||||
|
||||
const visibility = object.visible;
|
||||
|
||||
if ( bVisible === false || cache.get( object ) === true ) {
|
||||
|
||||
object.visible = bVisible;
|
||||
|
||||
}
|
||||
|
||||
cache.set( object, visibility );
|
||||
|
||||
}
|
||||
|
||||
} else if ( object.isPoints || object.isLine ) {
|
||||
|
||||
// the visibilty of points and lines is always set to false in order to
|
||||
// not affect the outline computation
|
||||
if ( bVisible === true ) {
|
||||
|
||||
object.visible = cache.get( object ); // restore
|
||||
|
||||
} else {
|
||||
|
||||
cache.set( object, object.visible );
|
||||
object.visible = bVisible;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.renderScene.traverse( VisibilityChangeCallBack );
|
||||
|
||||
}
|
||||
|
||||
updateTextureMatrix() {
|
||||
|
||||
this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0 );
|
||||
this.textureMatrix.multiply( this.renderCamera.projectionMatrix );
|
||||
this.textureMatrix.multiply( this.renderCamera.matrixWorldInverse );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
|
||||
|
||||
if ( this.selectedObjects.length > 0 ) {
|
||||
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
this.oldClearAlpha = renderer.getClearAlpha();
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( false );
|
||||
renderer.setClearColor( 0xffffff, 1 ); // Make selected objects invisible
|
||||
|
||||
this.changeVisibilityOfSelectedObjects( false );
|
||||
const currentBackground = this.renderScene.background;
|
||||
this.renderScene.background = null; // 1. Draw Non Selected objects in the depth buffer
|
||||
|
||||
this.renderScene.overrideMaterial = this.depthMaterial;
|
||||
renderer.setRenderTarget( this.renderTargetDepthBuffer );
|
||||
renderer.clear();
|
||||
renderer.render( this.renderScene, this.renderCamera ); // Make selected objects visible
|
||||
|
||||
this.changeVisibilityOfSelectedObjects( true );
|
||||
|
||||
this._visibilityCache.clear(); // Update Texture Matrix for Depth compare
|
||||
|
||||
|
||||
this.updateTextureMatrix(); // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
|
||||
|
||||
this.changeVisibilityOfNonSelectedObjects( false );
|
||||
this.renderScene.overrideMaterial = this.prepareMaskMaterial;
|
||||
this.prepareMaskMaterial.uniforms[ 'cameraNearFar' ].value.set( this.renderCamera.near, this.renderCamera.far );
|
||||
this.prepareMaskMaterial.uniforms[ 'depthTexture' ].value = this.renderTargetDepthBuffer.texture;
|
||||
this.prepareMaskMaterial.uniforms[ 'textureMatrix' ].value = this.textureMatrix;
|
||||
renderer.setRenderTarget( this.renderTargetMaskBuffer );
|
||||
renderer.clear();
|
||||
renderer.render( this.renderScene, this.renderCamera );
|
||||
this.renderScene.overrideMaterial = null;
|
||||
this.changeVisibilityOfNonSelectedObjects( true );
|
||||
|
||||
this._visibilityCache.clear();
|
||||
|
||||
this.renderScene.background = currentBackground; // 2. Downsample to Half resolution
|
||||
|
||||
this.fsQuad.material = this.materialCopy;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetMaskBuffer.texture;
|
||||
renderer.setRenderTarget( this.renderTargetMaskDownSampleBuffer );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
this.tempPulseColor1.copy( this.visibleEdgeColor );
|
||||
this.tempPulseColor2.copy( this.hiddenEdgeColor );
|
||||
|
||||
if ( this.pulsePeriod > 0 ) {
|
||||
|
||||
const scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2;
|
||||
this.tempPulseColor1.multiplyScalar( scalar );
|
||||
this.tempPulseColor2.multiplyScalar( scalar );
|
||||
|
||||
} // 3. Apply Edge Detection THREE.Pass
|
||||
|
||||
|
||||
this.fsQuad.material = this.edgeDetectionMaterial;
|
||||
this.edgeDetectionMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskDownSampleBuffer.texture;
|
||||
this.edgeDetectionMaterial.uniforms[ 'texSize' ].value.set( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );
|
||||
this.edgeDetectionMaterial.uniforms[ 'visibleEdgeColor' ].value = this.tempPulseColor1;
|
||||
this.edgeDetectionMaterial.uniforms[ 'hiddenEdgeColor' ].value = this.tempPulseColor2;
|
||||
renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // 4. Apply Blur on Half res
|
||||
|
||||
this.fsQuad.material = this.separableBlurMaterial1;
|
||||
this.separableBlurMaterial1.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX;
|
||||
this.separableBlurMaterial1.uniforms[ 'kernelRadius' ].value = this.edgeThickness;
|
||||
renderer.setRenderTarget( this.renderTargetBlurBuffer1 );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
this.separableBlurMaterial1.uniforms[ 'colorTexture' ].value = this.renderTargetBlurBuffer1.texture;
|
||||
this.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY;
|
||||
renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // Apply Blur on quarter res
|
||||
|
||||
this.fsQuad.material = this.separableBlurMaterial2;
|
||||
this.separableBlurMaterial2.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX;
|
||||
renderer.setRenderTarget( this.renderTargetBlurBuffer2 );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
this.separableBlurMaterial2.uniforms[ 'colorTexture' ].value = this.renderTargetBlurBuffer2.texture;
|
||||
this.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY;
|
||||
renderer.setRenderTarget( this.renderTargetEdgeBuffer2 );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // Blend it additively over the input texture
|
||||
|
||||
this.fsQuad.material = this.overlayMaterial;
|
||||
this.overlayMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskBuffer.texture;
|
||||
this.overlayMaterial.uniforms[ 'edgeTexture1' ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.overlayMaterial.uniforms[ 'edgeTexture2' ].value = this.renderTargetEdgeBuffer2.texture;
|
||||
this.overlayMaterial.uniforms[ 'patternTexture' ].value = this.patternTexture;
|
||||
this.overlayMaterial.uniforms[ 'edgeStrength' ].value = this.edgeStrength;
|
||||
this.overlayMaterial.uniforms[ 'edgeGlow' ].value = this.edgeGlow;
|
||||
this.overlayMaterial.uniforms[ 'usePatternTexture' ].value = this.usePatternTexture;
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
|
||||
renderer.setRenderTarget( readBuffer );
|
||||
this.fsQuad.render( renderer );
|
||||
renderer.setClearColor( this._oldClearColor, this.oldClearAlpha );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
this.fsQuad.material = this.materialCopy;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getPrepareMaskMaterial() {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
uniforms: {
|
||||
'depthTexture': {
|
||||
value: null
|
||||
},
|
||||
'cameraNearFar': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
},
|
||||
'textureMatrix': {
|
||||
value: null
|
||||
}
|
||||
},
|
||||
vertexShader: `#include <morphtarget_pars_vertex>
|
||||
#include <skinning_pars_vertex>
|
||||
|
||||
varying vec4 projTexCoord;
|
||||
varying vec4 vPosition;
|
||||
uniform mat4 textureMatrix;
|
||||
|
||||
void main() {
|
||||
|
||||
#include <skinbase_vertex>
|
||||
#include <begin_vertex>
|
||||
#include <morphtarget_vertex>
|
||||
#include <skinning_vertex>
|
||||
#include <project_vertex>
|
||||
|
||||
vPosition = mvPosition;
|
||||
vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
|
||||
projTexCoord = textureMatrix * worldPosition;
|
||||
|
||||
}`,
|
||||
fragmentShader: `#include <packing>
|
||||
varying vec4 vPosition;
|
||||
varying vec4 projTexCoord;
|
||||
uniform sampler2D depthTexture;
|
||||
uniform vec2 cameraNearFar;
|
||||
|
||||
void main() {
|
||||
|
||||
float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));
|
||||
float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );
|
||||
float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;
|
||||
gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);
|
||||
|
||||
}`
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
getEdgeDetectionMaterial() {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
uniforms: {
|
||||
'maskTexture': {
|
||||
value: null
|
||||
},
|
||||
'texSize': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
},
|
||||
'visibleEdgeColor': {
|
||||
value: new THREE.Vector3( 1.0, 1.0, 1.0 )
|
||||
},
|
||||
'hiddenEdgeColor': {
|
||||
value: new THREE.Vector3( 1.0, 1.0, 1.0 )
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: `varying vec2 vUv;
|
||||
|
||||
uniform sampler2D maskTexture;
|
||||
uniform vec2 texSize;
|
||||
uniform vec3 visibleEdgeColor;
|
||||
uniform vec3 hiddenEdgeColor;
|
||||
|
||||
void main() {
|
||||
vec2 invSize = 1.0 / texSize;
|
||||
vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);
|
||||
vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);
|
||||
vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);
|
||||
vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);
|
||||
vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);
|
||||
float diff1 = (c1.r - c2.r)*0.5;
|
||||
float diff2 = (c3.r - c4.r)*0.5;
|
||||
float d = length( vec2(diff1, diff2) );
|
||||
float a1 = min(c1.g, c2.g);
|
||||
float a2 = min(c3.g, c4.g);
|
||||
float visibilityFactor = min(a1, a2);
|
||||
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;
|
||||
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);
|
||||
}`
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
getSeperableBlurMaterial( maxRadius ) {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
defines: {
|
||||
'MAX_RADIUS': maxRadius
|
||||
},
|
||||
uniforms: {
|
||||
'colorTexture': {
|
||||
value: null
|
||||
},
|
||||
'texSize': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
},
|
||||
'direction': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
},
|
||||
'kernelRadius': {
|
||||
value: 1.0
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: `#include <common>
|
||||
varying vec2 vUv;
|
||||
uniform sampler2D colorTexture;
|
||||
uniform vec2 texSize;
|
||||
uniform vec2 direction;
|
||||
uniform float kernelRadius;
|
||||
|
||||
float gaussianPdf(in float x, in float sigma) {
|
||||
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 invSize = 1.0 / texSize;
|
||||
float weightSum = gaussianPdf(0.0, kernelRadius);
|
||||
vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;
|
||||
vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);
|
||||
vec2 uvOffset = delta;
|
||||
for( int i = 1; i <= MAX_RADIUS; i ++ ) {
|
||||
float w = gaussianPdf(uvOffset.x, kernelRadius);
|
||||
vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);
|
||||
vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);
|
||||
diffuseSum += ((sample1 + sample2) * w);
|
||||
weightSum += (2.0 * w);
|
||||
uvOffset += delta;
|
||||
}
|
||||
gl_FragColor = diffuseSum/weightSum;
|
||||
}`
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
getOverlayMaterial() {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
uniforms: {
|
||||
'maskTexture': {
|
||||
value: null
|
||||
},
|
||||
'edgeTexture1': {
|
||||
value: null
|
||||
},
|
||||
'edgeTexture2': {
|
||||
value: null
|
||||
},
|
||||
'patternTexture': {
|
||||
value: null
|
||||
},
|
||||
'edgeStrength': {
|
||||
value: 1.0
|
||||
},
|
||||
'edgeGlow': {
|
||||
value: 1.0
|
||||
},
|
||||
'usePatternTexture': {
|
||||
value: 0.0
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: `varying vec2 vUv;
|
||||
|
||||
uniform sampler2D maskTexture;
|
||||
uniform sampler2D edgeTexture1;
|
||||
uniform sampler2D edgeTexture2;
|
||||
uniform sampler2D patternTexture;
|
||||
uniform float edgeStrength;
|
||||
uniform float edgeGlow;
|
||||
uniform bool usePatternTexture;
|
||||
|
||||
void main() {
|
||||
vec4 edgeValue1 = texture2D(edgeTexture1, vUv);
|
||||
vec4 edgeValue2 = texture2D(edgeTexture2, vUv);
|
||||
vec4 maskColor = texture2D(maskTexture, vUv);
|
||||
vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);
|
||||
float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;
|
||||
vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;
|
||||
vec4 finalColor = edgeStrength * maskColor.r * edgeValue;
|
||||
if(usePatternTexture)
|
||||
finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);
|
||||
gl_FragColor = finalColor;
|
||||
}`,
|
||||
blending: THREE.AdditiveBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
transparent: true
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
|
||||
OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );
|
||||
|
||||
THREE.OutlinePass = OutlinePass;
|
||||
|
||||
} )();
|
||||
75
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/Pass.js
generated
vendored
Normal file
75
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/Pass.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
( function () {
|
||||
|
||||
class Pass {
|
||||
|
||||
constructor() {
|
||||
|
||||
// if set to true, the pass is processed by the composer
|
||||
this.enabled = true; // if set to true, the pass indicates to swap read and write buffer after rendering
|
||||
|
||||
this.needsSwap = true; // if set to true, the pass clears its buffer before rendering
|
||||
|
||||
this.clear = false; // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
|
||||
|
||||
this.renderToScreen = false;
|
||||
|
||||
}
|
||||
|
||||
setSize() {}
|
||||
|
||||
render() {
|
||||
|
||||
console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
|
||||
|
||||
}
|
||||
|
||||
} // Helper for passes that need to fill the viewport with a single quad.
|
||||
|
||||
|
||||
const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); // https://github.com/mrdoob/three.js/pull/21358
|
||||
|
||||
|
||||
const _geometry = new THREE.BufferGeometry();
|
||||
|
||||
_geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
|
||||
|
||||
_geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
|
||||
|
||||
class FullScreenQuad {
|
||||
|
||||
constructor( material ) {
|
||||
|
||||
this._mesh = new THREE.Mesh( _geometry, material );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this._mesh.geometry.dispose();
|
||||
|
||||
}
|
||||
|
||||
render( renderer ) {
|
||||
|
||||
renderer.render( this._mesh, _camera );
|
||||
|
||||
}
|
||||
|
||||
get material() {
|
||||
|
||||
return this._mesh.material;
|
||||
|
||||
}
|
||||
|
||||
set material( value ) {
|
||||
|
||||
this._mesh.material = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.FullScreenQuad = FullScreenQuad;
|
||||
THREE.Pass = Pass;
|
||||
|
||||
} )();
|
||||
74
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/RenderPass.js
generated
vendored
Normal file
74
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/RenderPass.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
( function () {
|
||||
|
||||
class RenderPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
|
||||
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.overrideMaterial = overrideMaterial;
|
||||
this.clearColor = clearColor;
|
||||
this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0;
|
||||
this.clear = true;
|
||||
this.clearDepth = false;
|
||||
this.needsSwap = false;
|
||||
this._oldClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
let oldClearAlpha, oldOverrideMaterial;
|
||||
|
||||
if ( this.overrideMaterial !== undefined ) {
|
||||
|
||||
oldOverrideMaterial = this.scene.overrideMaterial;
|
||||
this.scene.overrideMaterial = this.overrideMaterial;
|
||||
|
||||
}
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
oldClearAlpha = renderer.getClearAlpha();
|
||||
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
||||
|
||||
}
|
||||
|
||||
if ( this.clearDepth ) {
|
||||
|
||||
renderer.clearDepth();
|
||||
|
||||
}
|
||||
|
||||
renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
|
||||
|
||||
if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
|
||||
renderer.render( this.scene, this.camera );
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
renderer.setClearColor( this._oldClearColor, oldClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
if ( this.overrideMaterial !== undefined ) {
|
||||
|
||||
this.scene.overrideMaterial = oldOverrideMaterial;
|
||||
|
||||
}
|
||||
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.RenderPass = RenderPass;
|
||||
|
||||
} )();
|
||||
371
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SAOPass.js
generated
vendored
Normal file
371
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SAOPass.js
generated
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
* SAO implementation inspired from bhouston previous SAO work
|
||||
*/
|
||||
|
||||
class SAOPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera, useDepthTexture = false, useNormals = false, resolution = new THREE.Vector2( 256, 256 ) ) {
|
||||
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.clear = true;
|
||||
this.needsSwap = false;
|
||||
this.supportsDepthTextureExtension = useDepthTexture;
|
||||
this.supportsNormalTexture = useNormals;
|
||||
this.originalClearColor = new THREE.Color();
|
||||
this._oldClearColor = new THREE.Color();
|
||||
this.oldClearAlpha = 1;
|
||||
this.params = {
|
||||
output: 0,
|
||||
saoBias: 0.5,
|
||||
saoIntensity: 0.18,
|
||||
saoScale: 1,
|
||||
saoKernelRadius: 100,
|
||||
saoMinResolution: 0,
|
||||
saoBlur: true,
|
||||
saoBlurRadius: 8,
|
||||
saoBlurStdDev: 4,
|
||||
saoBlurDepthCutoff: 0.01
|
||||
};
|
||||
this.resolution = new THREE.Vector2( resolution.x, resolution.y );
|
||||
this.saoRenderTarget = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
|
||||
this.beautyRenderTarget = this.saoRenderTarget.clone();
|
||||
this.normalRenderTarget = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.depthRenderTarget = this.normalRenderTarget.clone();
|
||||
let depthTexture;
|
||||
|
||||
if ( this.supportsDepthTextureExtension ) {
|
||||
|
||||
depthTexture = new THREE.DepthTexture();
|
||||
depthTexture.type = THREE.UnsignedShortType;
|
||||
this.beautyRenderTarget.depthTexture = depthTexture;
|
||||
this.beautyRenderTarget.depthBuffer = true;
|
||||
|
||||
}
|
||||
|
||||
this.depthMaterial = new THREE.MeshDepthMaterial();
|
||||
this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
|
||||
this.depthMaterial.blending = THREE.NoBlending;
|
||||
this.normalMaterial = new THREE.MeshNormalMaterial();
|
||||
this.normalMaterial.blending = THREE.NoBlending;
|
||||
|
||||
if ( THREE.SAOShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SAOPass relies on THREE.SAOShader' );
|
||||
|
||||
}
|
||||
|
||||
this.saoMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SAOShader.defines ),
|
||||
fragmentShader: THREE.SAOShader.fragmentShader,
|
||||
vertexShader: THREE.SAOShader.vertexShader,
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SAOShader.uniforms )
|
||||
} );
|
||||
this.saoMaterial.extensions.derivatives = true;
|
||||
this.saoMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
|
||||
this.saoMaterial.defines[ 'NORMAL_TEXTURE' ] = this.supportsNormalTexture ? 1 : 0;
|
||||
this.saoMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
|
||||
this.saoMaterial.uniforms[ 'tDepth' ].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
|
||||
this.saoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
|
||||
this.saoMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
|
||||
this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
|
||||
this.saoMaterial.uniforms[ 'cameraProjectionMatrix' ].value = this.camera.projectionMatrix;
|
||||
this.saoMaterial.blending = THREE.NoBlending;
|
||||
|
||||
if ( THREE.DepthLimitedBlurShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SAOPass relies on THREE.DepthLimitedBlurShader' );
|
||||
|
||||
}
|
||||
|
||||
this.vBlurMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.DepthLimitedBlurShader.uniforms ),
|
||||
defines: Object.assign( {}, THREE.DepthLimitedBlurShader.defines ),
|
||||
vertexShader: THREE.DepthLimitedBlurShader.vertexShader,
|
||||
fragmentShader: THREE.DepthLimitedBlurShader.fragmentShader
|
||||
} );
|
||||
this.vBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
|
||||
this.vBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
|
||||
this.vBlurMaterial.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture;
|
||||
this.vBlurMaterial.uniforms[ 'tDepth' ].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
|
||||
this.vBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
|
||||
this.vBlurMaterial.blending = THREE.NoBlending;
|
||||
this.hBlurMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.DepthLimitedBlurShader.uniforms ),
|
||||
defines: Object.assign( {}, THREE.DepthLimitedBlurShader.defines ),
|
||||
vertexShader: THREE.DepthLimitedBlurShader.vertexShader,
|
||||
fragmentShader: THREE.DepthLimitedBlurShader.fragmentShader
|
||||
} );
|
||||
this.hBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
|
||||
this.hBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
|
||||
this.hBlurMaterial.uniforms[ 'tDiffuse' ].value = this.blurIntermediateRenderTarget.texture;
|
||||
this.hBlurMaterial.uniforms[ 'tDepth' ].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
|
||||
this.hBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
|
||||
this.hBlurMaterial.blending = THREE.NoBlending;
|
||||
|
||||
if ( THREE.CopyShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SAOPass relies on THREE.CopyShader' );
|
||||
|
||||
}
|
||||
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
|
||||
vertexShader: THREE.CopyShader.vertexShader,
|
||||
fragmentShader: THREE.CopyShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.materialCopy.transparent = true;
|
||||
this.materialCopy.depthTest = false;
|
||||
this.materialCopy.depthWrite = false;
|
||||
this.materialCopy.blending = THREE.CustomBlending;
|
||||
this.materialCopy.blendSrc = THREE.DstColorFactor;
|
||||
this.materialCopy.blendDst = THREE.ZeroFactor;
|
||||
this.materialCopy.blendEquation = THREE.AddEquation;
|
||||
this.materialCopy.blendSrcAlpha = THREE.DstAlphaFactor;
|
||||
this.materialCopy.blendDstAlpha = THREE.ZeroFactor;
|
||||
this.materialCopy.blendEquationAlpha = THREE.AddEquation;
|
||||
|
||||
if ( THREE.UnpackDepthRGBAShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SAOPass relies on THREE.UnpackDepthRGBAShader' );
|
||||
|
||||
}
|
||||
|
||||
this.depthCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.UnpackDepthRGBAShader.uniforms ),
|
||||
vertexShader: THREE.UnpackDepthRGBAShader.vertexShader,
|
||||
fragmentShader: THREE.UnpackDepthRGBAShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive*/
|
||||
) {
|
||||
|
||||
// Rendering readBuffer first when rendering to screen
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
this.materialCopy.blending = THREE.NoBlending;
|
||||
this.materialCopy.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.materialCopy.needsUpdate = true;
|
||||
this.renderPass( renderer, this.materialCopy, null );
|
||||
|
||||
}
|
||||
|
||||
if ( this.params.output === 1 ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
this.oldClearAlpha = renderer.getClearAlpha();
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
renderer.setRenderTarget( this.depthRenderTarget );
|
||||
renderer.clear();
|
||||
this.saoMaterial.uniforms[ 'bias' ].value = this.params.saoBias;
|
||||
this.saoMaterial.uniforms[ 'intensity' ].value = this.params.saoIntensity;
|
||||
this.saoMaterial.uniforms[ 'scale' ].value = this.params.saoScale;
|
||||
this.saoMaterial.uniforms[ 'kernelRadius' ].value = this.params.saoKernelRadius;
|
||||
this.saoMaterial.uniforms[ 'minResolution' ].value = this.params.saoMinResolution;
|
||||
this.saoMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.saoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // this.saoMaterial.uniforms['randomSeed'].value = Math.random();
|
||||
|
||||
const depthCutoff = this.params.saoBlurDepthCutoff * ( this.camera.far - this.camera.near );
|
||||
this.vBlurMaterial.uniforms[ 'depthCutoff' ].value = depthCutoff;
|
||||
this.hBlurMaterial.uniforms[ 'depthCutoff' ].value = depthCutoff;
|
||||
this.vBlurMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.vBlurMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
||||
this.hBlurMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.hBlurMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
||||
this.params.saoBlurRadius = Math.floor( this.params.saoBlurRadius );
|
||||
|
||||
if ( this.prevStdDev !== this.params.saoBlurStdDev || this.prevNumSamples !== this.params.saoBlurRadius ) {
|
||||
|
||||
THREE.BlurShaderUtils.configure( this.vBlurMaterial, this.params.saoBlurRadius, this.params.saoBlurStdDev, new THREE.Vector2( 0, 1 ) );
|
||||
THREE.BlurShaderUtils.configure( this.hBlurMaterial, this.params.saoBlurRadius, this.params.saoBlurStdDev, new THREE.Vector2( 1, 0 ) );
|
||||
this.prevStdDev = this.params.saoBlurStdDev;
|
||||
this.prevNumSamples = this.params.saoBlurRadius;
|
||||
|
||||
} // Rendering scene to depth texture
|
||||
|
||||
|
||||
renderer.setClearColor( 0x000000 );
|
||||
renderer.setRenderTarget( this.beautyRenderTarget );
|
||||
renderer.clear();
|
||||
renderer.render( this.scene, this.camera ); // Re-render scene if depth texture extension is not supported
|
||||
|
||||
if ( ! this.supportsDepthTextureExtension ) {
|
||||
|
||||
// Clear rule : far clipping plane in both RGBA and Basic encoding
|
||||
this.renderOverride( renderer, this.depthMaterial, this.depthRenderTarget, 0x000000, 1.0 );
|
||||
|
||||
}
|
||||
|
||||
if ( this.supportsNormalTexture ) {
|
||||
|
||||
// Clear rule : default normal is facing the camera
|
||||
this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
|
||||
|
||||
} // Rendering SAO texture
|
||||
|
||||
|
||||
this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 ); // Blurring SAO texture
|
||||
|
||||
if ( this.params.saoBlur ) {
|
||||
|
||||
this.renderPass( renderer, this.vBlurMaterial, this.blurIntermediateRenderTarget, 0xffffff, 1.0 );
|
||||
this.renderPass( renderer, this.hBlurMaterial, this.saoRenderTarget, 0xffffff, 1.0 );
|
||||
|
||||
}
|
||||
|
||||
let outputMaterial = this.materialCopy; // Setting up SAO rendering
|
||||
|
||||
if ( this.params.output === 3 ) {
|
||||
|
||||
if ( this.supportsDepthTextureExtension ) {
|
||||
|
||||
this.materialCopy.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.materialCopy.needsUpdate = true;
|
||||
|
||||
} else {
|
||||
|
||||
this.depthCopy.uniforms[ 'tDiffuse' ].value = this.depthRenderTarget.texture;
|
||||
this.depthCopy.needsUpdate = true;
|
||||
outputMaterial = this.depthCopy;
|
||||
|
||||
}
|
||||
|
||||
} else if ( this.params.output === 4 ) {
|
||||
|
||||
this.materialCopy.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
|
||||
this.materialCopy.needsUpdate = true;
|
||||
|
||||
} else {
|
||||
|
||||
this.materialCopy.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture;
|
||||
this.materialCopy.needsUpdate = true;
|
||||
|
||||
} // Blending depends on output, only want a THREE.CustomBlending when showing SAO
|
||||
|
||||
|
||||
if ( this.params.output === 0 ) {
|
||||
|
||||
outputMaterial.blending = THREE.CustomBlending;
|
||||
|
||||
} else {
|
||||
|
||||
outputMaterial.blending = THREE.NoBlending;
|
||||
|
||||
} // Rendering SAOPass result on top of previous pass
|
||||
|
||||
|
||||
this.renderPass( renderer, outputMaterial, this.renderToScreen ? null : readBuffer );
|
||||
renderer.setClearColor( this._oldClearColor, this.oldClearAlpha );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
// save original state
|
||||
renderer.getClearColor( this.originalClearColor );
|
||||
const originalClearAlpha = renderer.getClearAlpha();
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget ); // setup pass state
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = passMaterial;
|
||||
this.fsQuad.render( renderer ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
renderer.getClearColor( this.originalClearColor );
|
||||
const originalClearAlpha = renderer.getClearAlpha();
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = overrideMaterial;
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.overrideMaterial = null; // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.beautyRenderTarget.setSize( width, height );
|
||||
this.saoRenderTarget.setSize( width, height );
|
||||
this.blurIntermediateRenderTarget.setSize( width, height );
|
||||
this.normalRenderTarget.setSize( width, height );
|
||||
this.depthRenderTarget.setSize( width, height );
|
||||
this.saoMaterial.uniforms[ 'size' ].value.set( width, height );
|
||||
this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
|
||||
this.saoMaterial.uniforms[ 'cameraProjectionMatrix' ].value = this.camera.projectionMatrix;
|
||||
this.saoMaterial.needsUpdate = true;
|
||||
this.vBlurMaterial.uniforms[ 'size' ].value.set( width, height );
|
||||
this.vBlurMaterial.needsUpdate = true;
|
||||
this.hBlurMaterial.uniforms[ 'size' ].value.set( width, height );
|
||||
this.hBlurMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SAOPass.OUTPUT = {
|
||||
'Beauty': 1,
|
||||
'Default': 0,
|
||||
'SAO': 2,
|
||||
'Depth': 3,
|
||||
'Normal': 4
|
||||
};
|
||||
|
||||
THREE.SAOPass = SAOPass;
|
||||
|
||||
} )();
|
||||
153
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SMAAPass.js
generated
vendored
Normal file
153
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SMAAPass.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
161
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSAARenderPass.js
generated
vendored
Normal file
161
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSAARenderPass.js
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
*
|
||||
* Supersample Anti-Aliasing Render THREE.Pass
|
||||
*
|
||||
* This manual approach to SSAA re-renders the scene ones for each sample with camera jitter and accumulates the results.
|
||||
*
|
||||
* References: https://en.wikipedia.org/wiki/Supersampling
|
||||
*
|
||||
*/
|
||||
|
||||
class SSAARenderPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera, clearColor, clearAlpha ) {
|
||||
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.sampleLevel = 4; // specified as n, where the number of samples is 2^n, so sampleLevel = 4, is 2^4 samples, 16.
|
||||
|
||||
this.unbiased = true; // as we need to clear the buffer in this pass, clearColor must be set to something, defaults to black.
|
||||
|
||||
this.clearColor = clearColor !== undefined ? clearColor : 0x000000;
|
||||
this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0;
|
||||
this._oldClearColor = new THREE.Color();
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.SSAARenderPass relies on THREE.CopyShader' );
|
||||
const copyShader = THREE.CopyShader;
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.copyMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
premultipliedAlpha: true,
|
||||
transparent: true,
|
||||
blending: THREE.AdditiveBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.copyMaterial );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
if ( this.sampleRenderTarget ) {
|
||||
|
||||
this.sampleRenderTarget.dispose();
|
||||
this.sampleRenderTarget = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
if ( this.sampleRenderTarget ) this.sampleRenderTarget.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer ) {
|
||||
|
||||
if ( ! this.sampleRenderTarget ) {
|
||||
|
||||
this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.sampleRenderTarget.texture.name = 'SSAARenderPass.sample';
|
||||
|
||||
}
|
||||
|
||||
const jitterOffsets = _JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
|
||||
|
||||
const autoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
const oldClearAlpha = renderer.getClearAlpha();
|
||||
const baseSampleWeight = 1.0 / jitterOffsets.length;
|
||||
const roundingRange = 1 / 32;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.sampleRenderTarget.texture;
|
||||
const viewOffset = {
|
||||
fullWidth: readBuffer.width,
|
||||
fullHeight: readBuffer.height,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
width: readBuffer.width,
|
||||
height: readBuffer.height
|
||||
};
|
||||
const originalViewOffset = Object.assign( {}, this.camera.view );
|
||||
if ( originalViewOffset.enabled ) Object.assign( viewOffset, originalViewOffset ); // render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
|
||||
|
||||
for ( let i = 0; i < jitterOffsets.length; i ++ ) {
|
||||
|
||||
const jitterOffset = jitterOffsets[ i ];
|
||||
|
||||
if ( this.camera.setViewOffset ) {
|
||||
|
||||
this.camera.setViewOffset( viewOffset.fullWidth, viewOffset.fullHeight, viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
|
||||
viewOffset.width, viewOffset.height );
|
||||
|
||||
}
|
||||
|
||||
let sampleWeight = baseSampleWeight;
|
||||
|
||||
if ( this.unbiased ) {
|
||||
|
||||
// the theory is that equal weights for each sample lead to an accumulation of rounding errors.
|
||||
// The following equation varies the sampleWeight per sample so that it is uniformly distributed
|
||||
// across a range of values whose rounding errors cancel each other out.
|
||||
const uniformCenteredDistribution = - 0.5 + ( i + 0.5 ) / jitterOffsets.length;
|
||||
sampleWeight += roundingRange * uniformCenteredDistribution;
|
||||
|
||||
}
|
||||
|
||||
this.copyUniforms[ 'opacity' ].value = sampleWeight;
|
||||
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
||||
renderer.setRenderTarget( this.sampleRenderTarget );
|
||||
renderer.clear();
|
||||
renderer.render( this.scene, this.camera );
|
||||
renderer.setRenderTarget( this.renderToScreen ? null : writeBuffer );
|
||||
|
||||
if ( i === 0 ) {
|
||||
|
||||
renderer.setClearColor( 0x000000, 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
if ( this.camera.setViewOffset && originalViewOffset.enabled ) {
|
||||
|
||||
this.camera.setViewOffset( originalViewOffset.fullWidth, originalViewOffset.fullHeight, originalViewOffset.offsetX, originalViewOffset.offsetY, originalViewOffset.width, originalViewOffset.height );
|
||||
|
||||
} else if ( this.camera.clearViewOffset ) {
|
||||
|
||||
this.camera.clearViewOffset();
|
||||
|
||||
}
|
||||
|
||||
renderer.autoClear = autoClear;
|
||||
renderer.setClearColor( this._oldClearColor, oldClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
} // These jitter vectors are specified in integers because it is easier.
|
||||
// I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5)
|
||||
// before being used, thus these integers need to be scaled by 1/16.
|
||||
//
|
||||
// Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
|
||||
|
||||
|
||||
const _JitterVectors = [[[ 0, 0 ]], [[ 4, 4 ], [ - 4, - 4 ]], [[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]], [[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ], [ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]], [[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ], [ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ], [ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ], [ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]], [[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ], [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ], [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ], [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ], [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ], [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ], [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ], [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]]];
|
||||
|
||||
THREE.SSAARenderPass = SSAARenderPass;
|
||||
|
||||
} )();
|
||||
351
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSAOPass.js
generated
vendored
Normal file
351
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSAOPass.js
generated
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
( function () {
|
||||
|
||||
class SSAOPass extends THREE.Pass {
|
||||
|
||||
constructor( scene, camera, width, height ) {
|
||||
|
||||
super();
|
||||
this.width = width !== undefined ? width : 512;
|
||||
this.height = height !== undefined ? height : 512;
|
||||
this.clear = true;
|
||||
this.camera = camera;
|
||||
this.scene = scene;
|
||||
this.kernelRadius = 8;
|
||||
this.kernelSize = 32;
|
||||
this.kernel = [];
|
||||
this.noiseTexture = null;
|
||||
this.output = 0;
|
||||
this.minDistance = 0.005;
|
||||
this.maxDistance = 0.1;
|
||||
this._visibilityCache = new Map(); //
|
||||
|
||||
this.generateSampleKernel();
|
||||
this.generateRandomKernelRotations(); // beauty render target
|
||||
|
||||
const depthTexture = new THREE.DepthTexture();
|
||||
depthTexture.format = THREE.DepthStencilFormat;
|
||||
depthTexture.type = THREE.UnsignedInt248Type;
|
||||
this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height ); // normal render target with depth buffer
|
||||
|
||||
this.normalRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
depthTexture: depthTexture
|
||||
} ); // ssao render target
|
||||
|
||||
this.ssaoRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height );
|
||||
this.blurRenderTarget = this.ssaoRenderTarget.clone(); // ssao material
|
||||
|
||||
if ( THREE.SSAOShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SSAOPass: The pass relies on THREE.SSAOShader.' );
|
||||
|
||||
}
|
||||
|
||||
this.ssaoMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSAOShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSAOShader.uniforms ),
|
||||
vertexShader: THREE.SSAOShader.vertexShader,
|
||||
fragmentShader: THREE.SSAOShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.ssaoMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.ssaoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
|
||||
this.ssaoMaterial.uniforms[ 'tDepth' ].value = this.normalRenderTarget.depthTexture;
|
||||
this.ssaoMaterial.uniforms[ 'tNoise' ].value = this.noiseTexture;
|
||||
this.ssaoMaterial.uniforms[ 'kernel' ].value = this.kernel;
|
||||
this.ssaoMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.ssaoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
||||
this.ssaoMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
|
||||
this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material
|
||||
|
||||
this.normalMaterial = new THREE.MeshNormalMaterial();
|
||||
this.normalMaterial.blending = THREE.NoBlending; // blur material
|
||||
|
||||
this.blurMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSAOBlurShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSAOBlurShader.uniforms ),
|
||||
vertexShader: THREE.SSAOBlurShader.vertexShader,
|
||||
fragmentShader: THREE.SSAOBlurShader.fragmentShader
|
||||
} );
|
||||
this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
|
||||
this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); // material for rendering the depth
|
||||
|
||||
this.depthRenderMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSAODepthShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSAODepthShader.uniforms ),
|
||||
vertexShader: THREE.SSAODepthShader.vertexShader,
|
||||
fragmentShader: THREE.SSAODepthShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.normalRenderTarget.depthTexture;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // material for rendering the content of a render target
|
||||
|
||||
this.copyMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
|
||||
vertexShader: THREE.CopyShader.vertexShader,
|
||||
fragmentShader: THREE.CopyShader.fragmentShader,
|
||||
transparent: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
blendSrc: THREE.DstColorFactor,
|
||||
blendDst: THREE.ZeroFactor,
|
||||
blendEquation: THREE.AddEquation,
|
||||
blendSrcAlpha: THREE.DstAlphaFactor,
|
||||
blendDstAlpha: THREE.ZeroFactor,
|
||||
blendEquationAlpha: THREE.AddEquation
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
this.originalClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
// dispose render targets
|
||||
this.beautyRenderTarget.dispose();
|
||||
this.normalRenderTarget.dispose();
|
||||
this.ssaoRenderTarget.dispose();
|
||||
this.blurRenderTarget.dispose(); // dispose materials
|
||||
|
||||
this.normalMaterial.dispose();
|
||||
this.blurMaterial.dispose();
|
||||
this.copyMaterial.dispose();
|
||||
this.depthRenderMaterial.dispose(); // dipsose full screen quad
|
||||
|
||||
this.fsQuad.dispose();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer
|
||||
/*, readBuffer, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
if ( renderer.capabilities.isWebGL2 === false ) this.noiseTexture.format = THREE.LuminanceFormat; // render beauty
|
||||
|
||||
renderer.setRenderTarget( this.beautyRenderTarget );
|
||||
renderer.clear();
|
||||
renderer.render( this.scene, this.camera ); // render normals and depth (honor only meshes, points and lines do not contribute to SSAO)
|
||||
|
||||
this.overrideVisibility();
|
||||
this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
|
||||
this.restoreVisibility(); // render SSAO
|
||||
|
||||
this.ssaoMaterial.uniforms[ 'kernelRadius' ].value = this.kernelRadius;
|
||||
this.ssaoMaterial.uniforms[ 'minDistance' ].value = this.minDistance;
|
||||
this.ssaoMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
|
||||
this.renderPass( renderer, this.ssaoMaterial, this.ssaoRenderTarget ); // render blur
|
||||
|
||||
this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget ); // output result to screen
|
||||
|
||||
switch ( this.output ) {
|
||||
|
||||
case SSAOPass.OUTPUT.SSAO:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSAOPass.OUTPUT.Blur:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSAOPass.OUTPUT.Beauty:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSAOPass.OUTPUT.Depth:
|
||||
this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSAOPass.OUTPUT.Normal:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSAOPass.OUTPUT.Default:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.CustomBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn( 'THREE.SSAOPass: Unknown output type.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
// save original state
|
||||
renderer.getClearColor( this.originalClearColor );
|
||||
const originalClearAlpha = renderer.getClearAlpha();
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget ); // setup pass state
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = passMaterial;
|
||||
this.fsQuad.render( renderer ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
renderer.getClearColor( this.originalClearColor );
|
||||
const originalClearAlpha = renderer.getClearAlpha();
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = overrideMaterial;
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.overrideMaterial = null; // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.beautyRenderTarget.setSize( width, height );
|
||||
this.ssaoRenderTarget.setSize( width, height );
|
||||
this.normalRenderTarget.setSize( width, height );
|
||||
this.blurRenderTarget.setSize( width, height );
|
||||
this.ssaoMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
||||
this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
|
||||
this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
||||
|
||||
}
|
||||
|
||||
generateSampleKernel() {
|
||||
|
||||
const kernelSize = this.kernelSize;
|
||||
const kernel = this.kernel;
|
||||
|
||||
for ( let i = 0; i < kernelSize; i ++ ) {
|
||||
|
||||
const sample = new THREE.Vector3();
|
||||
sample.x = Math.random() * 2 - 1;
|
||||
sample.y = Math.random() * 2 - 1;
|
||||
sample.z = Math.random();
|
||||
sample.normalize();
|
||||
let scale = i / kernelSize;
|
||||
scale = THREE.MathUtils.lerp( 0.1, 1, scale * scale );
|
||||
sample.multiplyScalar( scale );
|
||||
kernel.push( sample );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generateRandomKernelRotations() {
|
||||
|
||||
const width = 4,
|
||||
height = 4;
|
||||
|
||||
if ( THREE.SimplexNoise === undefined ) {
|
||||
|
||||
console.error( 'THREE.SSAOPass: The pass relies on THREE.SimplexNoise.' );
|
||||
|
||||
}
|
||||
|
||||
const simplex = new THREE.SimplexNoise();
|
||||
const size = width * height;
|
||||
const data = new Float32Array( size );
|
||||
|
||||
for ( let i = 0; i < size; i ++ ) {
|
||||
|
||||
const x = Math.random() * 2 - 1;
|
||||
const y = Math.random() * 2 - 1;
|
||||
const z = 0;
|
||||
data[ i ] = simplex.noise3d( x, y, z );
|
||||
|
||||
}
|
||||
|
||||
this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.RedFormat, THREE.FloatType );
|
||||
this.noiseTexture.wrapS = THREE.RepeatWrapping;
|
||||
this.noiseTexture.wrapT = THREE.RepeatWrapping;
|
||||
this.noiseTexture.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
overrideVisibility() {
|
||||
|
||||
const scene = this.scene;
|
||||
const cache = this._visibilityCache;
|
||||
scene.traverse( function ( object ) {
|
||||
|
||||
cache.set( object, object.visible );
|
||||
if ( object.isPoints || object.isLine ) object.visible = false;
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
restoreVisibility() {
|
||||
|
||||
const scene = this.scene;
|
||||
const cache = this._visibilityCache;
|
||||
scene.traverse( function ( object ) {
|
||||
|
||||
const visible = cache.get( object );
|
||||
object.visible = visible;
|
||||
|
||||
} );
|
||||
cache.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SSAOPass.OUTPUT = {
|
||||
'Default': 0,
|
||||
'SSAO': 1,
|
||||
'Blur': 2,
|
||||
'Beauty': 3,
|
||||
'Depth': 4,
|
||||
'Normal': 5
|
||||
};
|
||||
|
||||
THREE.SSAOPass = SSAOPass;
|
||||
|
||||
} )();
|
||||
555
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSRPass.js
generated
vendored
Normal file
555
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSRPass.js
generated
vendored
Normal file
@@ -0,0 +1,555 @@
|
||||
( function () {
|
||||
|
||||
class SSRPass extends THREE.Pass {
|
||||
|
||||
constructor( {
|
||||
renderer,
|
||||
scene,
|
||||
camera,
|
||||
width,
|
||||
height,
|
||||
selects,
|
||||
bouncing = false,
|
||||
groundReflector
|
||||
} ) {
|
||||
|
||||
super();
|
||||
this.width = width !== undefined ? width : 512;
|
||||
this.height = height !== undefined ? height : 512;
|
||||
this.clear = true;
|
||||
this.renderer = renderer;
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.groundReflector = groundReflector;
|
||||
this.opacity = THREE.SSRShader.uniforms.opacity.value;
|
||||
this.output = 0;
|
||||
this.maxDistance = THREE.SSRShader.uniforms.maxDistance.value;
|
||||
this.thickness = THREE.SSRShader.uniforms.thickness.value;
|
||||
this.tempColor = new THREE.Color();
|
||||
this._selects = selects;
|
||||
this.selective = Array.isArray( this._selects );
|
||||
Object.defineProperty( this, 'selects', {
|
||||
get() {
|
||||
|
||||
return this._selects;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._selects === val ) return;
|
||||
this._selects = val;
|
||||
|
||||
if ( Array.isArray( val ) ) {
|
||||
|
||||
this.selective = true;
|
||||
this.ssrMaterial.defines.SELECTIVE = true;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
|
||||
} else {
|
||||
|
||||
this.selective = false;
|
||||
this.ssrMaterial.defines.SELECTIVE = false;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this._bouncing = bouncing;
|
||||
Object.defineProperty( this, 'bouncing', {
|
||||
get() {
|
||||
|
||||
return this._bouncing;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._bouncing === val ) return;
|
||||
this._bouncing = val;
|
||||
|
||||
if ( val ) {
|
||||
|
||||
this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
|
||||
|
||||
} else {
|
||||
|
||||
this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this.blur = true;
|
||||
this._distanceAttenuation = THREE.SSRShader.defines.DISTANCE_ATTENUATION;
|
||||
Object.defineProperty( this, 'distanceAttenuation', {
|
||||
get() {
|
||||
|
||||
return this._distanceAttenuation;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._distanceAttenuation === val ) return;
|
||||
this._distanceAttenuation = val;
|
||||
this.ssrMaterial.defines.DISTANCE_ATTENUATION = val;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this._fresnel = THREE.SSRShader.defines.FRESNEL;
|
||||
Object.defineProperty( this, 'fresnel', {
|
||||
get() {
|
||||
|
||||
return this._fresnel;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._fresnel === val ) return;
|
||||
this._fresnel = val;
|
||||
this.ssrMaterial.defines.FRESNEL = val;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this._infiniteThick = THREE.SSRShader.defines.INFINITE_THICK;
|
||||
Object.defineProperty( this, 'infiniteThick', {
|
||||
get() {
|
||||
|
||||
return this._infiniteThick;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._infiniteThick === val ) return;
|
||||
this._infiniteThick = val;
|
||||
this.ssrMaterial.defines.INFINITE_THICK = val;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} ); // beauty render target with depth buffer
|
||||
|
||||
const depthTexture = new THREE.DepthTexture();
|
||||
depthTexture.type = THREE.UnsignedShortType;
|
||||
depthTexture.minFilter = THREE.NearestFilter;
|
||||
depthTexture.magFilter = THREE.NearestFilter;
|
||||
this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
depthTexture: depthTexture,
|
||||
depthBuffer: true
|
||||
} ); //for bouncing
|
||||
|
||||
this.prevRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} ); // normal render target
|
||||
|
||||
this.normalRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.HalfFloatType
|
||||
} ); // metalness render target
|
||||
|
||||
this.metalnessRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} ); // ssr render target
|
||||
|
||||
this.ssrRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} );
|
||||
this.blurRenderTarget = this.ssrRenderTarget.clone();
|
||||
this.blurRenderTarget2 = this.ssrRenderTarget.clone(); // this.blurRenderTarget3 = this.ssrRenderTarget.clone();
|
||||
// ssr material
|
||||
|
||||
if ( THREE.SSRShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SSRPass: The pass relies on THREE.SSRShader.' );
|
||||
|
||||
}
|
||||
|
||||
this.ssrMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRShader.defines, {
|
||||
MAX_STEP: Math.sqrt( this.width * this.width + this.height * this.height )
|
||||
} ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRShader.uniforms ),
|
||||
vertexShader: THREE.SSRShader.vertexShader,
|
||||
fragmentShader: THREE.SSRShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.ssrMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
|
||||
this.ssrMaterial.defines.SELECTIVE = this.selective;
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
this.ssrMaterial.uniforms[ 'tMetalness' ].value = this.metalnessRenderTarget.texture;
|
||||
this.ssrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.ssrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.ssrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
||||
this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness;
|
||||
this.ssrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
|
||||
this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material
|
||||
|
||||
this.normalMaterial = new THREE.MeshNormalMaterial();
|
||||
this.normalMaterial.blending = THREE.NoBlending; // metalnessOn material
|
||||
|
||||
this.metalnessOnMaterial = new THREE.MeshBasicMaterial( {
|
||||
color: 'white'
|
||||
} ); // metalnessOff material
|
||||
|
||||
this.metalnessOffMaterial = new THREE.MeshBasicMaterial( {
|
||||
color: 'black'
|
||||
} ); // blur material
|
||||
|
||||
this.blurMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRBlurShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRBlurShader.uniforms ),
|
||||
vertexShader: THREE.SSRBlurShader.vertexShader,
|
||||
fragmentShader: THREE.SSRBlurShader.fragmentShader
|
||||
} );
|
||||
this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
|
||||
this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height ); // blur material 2
|
||||
|
||||
this.blurMaterial2 = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRBlurShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRBlurShader.uniforms ),
|
||||
vertexShader: THREE.SSRBlurShader.vertexShader,
|
||||
fragmentShader: THREE.SSRBlurShader.fragmentShader
|
||||
} );
|
||||
this.blurMaterial2.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
|
||||
this.blurMaterial2.uniforms[ 'resolution' ].value.set( this.width, this.height ); // // blur material 3
|
||||
// this.blurMaterial3 = new THREE.ShaderMaterial({
|
||||
// defines: Object.assign({}, THREE.SSRBlurShader.defines),
|
||||
// uniforms: THREE.UniformsUtils.clone(THREE.SSRBlurShader.uniforms),
|
||||
// vertexShader: THREE.SSRBlurShader.vertexShader,
|
||||
// fragmentShader: THREE.SSRBlurShader.fragmentShader
|
||||
// });
|
||||
// this.blurMaterial3.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
|
||||
// this.blurMaterial3.uniforms['resolution'].value.set(this.width, this.height);
|
||||
// material for rendering the depth
|
||||
|
||||
this.depthRenderMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRDepthShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRDepthShader.uniforms ),
|
||||
vertexShader: THREE.SSRDepthShader.vertexShader,
|
||||
fragmentShader: THREE.SSRDepthShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // material for rendering the content of a render target
|
||||
|
||||
this.copyMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
|
||||
vertexShader: THREE.CopyShader.vertexShader,
|
||||
fragmentShader: THREE.CopyShader.fragmentShader,
|
||||
transparent: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
blendSrc: THREE.SrcAlphaFactor,
|
||||
blendDst: THREE.OneMinusSrcAlphaFactor,
|
||||
blendEquation: THREE.AddEquation,
|
||||
blendSrcAlpha: THREE.SrcAlphaFactor,
|
||||
blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
|
||||
blendEquationAlpha: THREE.AddEquation // premultipliedAlpha:true,
|
||||
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
this.originalClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
// dispose render targets
|
||||
this.beautyRenderTarget.dispose();
|
||||
this.prevRenderTarget.dispose();
|
||||
this.normalRenderTarget.dispose();
|
||||
this.metalnessRenderTarget.dispose();
|
||||
this.ssrRenderTarget.dispose();
|
||||
this.blurRenderTarget.dispose();
|
||||
this.blurRenderTarget2.dispose(); // this.blurRenderTarget3.dispose();
|
||||
// dispose materials
|
||||
|
||||
this.normalMaterial.dispose();
|
||||
this.metalnessOnMaterial.dispose();
|
||||
this.metalnessOffMaterial.dispose();
|
||||
this.blurMaterial.dispose();
|
||||
this.blurMaterial2.dispose();
|
||||
this.copyMaterial.dispose();
|
||||
this.depthRenderMaterial.dispose(); // dipsose full screen quad
|
||||
|
||||
this.fsQuad.dispose();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer
|
||||
/*, readBuffer, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
// render beauty and depth
|
||||
renderer.setRenderTarget( this.beautyRenderTarget );
|
||||
renderer.clear();
|
||||
|
||||
if ( this.groundReflector ) {
|
||||
|
||||
this.groundReflector.visible = false;
|
||||
this.groundReflector.doRender( this.renderer, this.scene, this.camera );
|
||||
this.groundReflector.visible = true;
|
||||
|
||||
}
|
||||
|
||||
renderer.render( this.scene, this.camera );
|
||||
if ( this.groundReflector ) this.groundReflector.visible = false; // render normals
|
||||
|
||||
this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 ); // render metalnesses
|
||||
|
||||
if ( this.selective ) {
|
||||
|
||||
this.renderMetalness( renderer, this.metalnessOnMaterial, this.metalnessRenderTarget, 0, 0 );
|
||||
|
||||
} // render SSR
|
||||
|
||||
|
||||
this.ssrMaterial.uniforms[ 'opacity' ].value = this.opacity;
|
||||
this.ssrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
|
||||
this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness;
|
||||
this.renderPass( renderer, this.ssrMaterial, this.ssrRenderTarget ); // render blur
|
||||
|
||||
if ( this.blur ) {
|
||||
|
||||
this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget );
|
||||
this.renderPass( renderer, this.blurMaterial2, this.blurRenderTarget2 ); // this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3);
|
||||
|
||||
} // output result to screen
|
||||
|
||||
|
||||
switch ( this.output ) {
|
||||
|
||||
case SSRPass.OUTPUT.Default:
|
||||
if ( this.bouncing ) {
|
||||
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
|
||||
if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NormalBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
|
||||
} else {
|
||||
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NormalBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SSRPass.OUTPUT.SSR:
|
||||
if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
|
||||
if ( this.bouncing ) {
|
||||
|
||||
if ( this.blur ) this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture; else this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NormalBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SSRPass.OUTPUT.Beauty:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRPass.OUTPUT.Depth:
|
||||
this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRPass.OUTPUT.Normal:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRPass.OUTPUT.Metalness:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.metalnessRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn( 'THREE.SSRPass: Unknown output type.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
// save original state
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget ); // setup pass state
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = passMaterial;
|
||||
this.fsQuad.render( renderer ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = overrideMaterial;
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.overrideMaterial = null; // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderMetalness( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.traverseVisible( child => {
|
||||
|
||||
child._SSRPassBackupMaterial = child.material;
|
||||
|
||||
if ( this._selects.includes( child ) ) {
|
||||
|
||||
child.material = this.metalnessOnMaterial;
|
||||
|
||||
} else {
|
||||
|
||||
child.material = this.metalnessOffMaterial;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.traverseVisible( child => {
|
||||
|
||||
child.material = child._SSRPassBackupMaterial;
|
||||
|
||||
} ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.ssrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
|
||||
this.ssrMaterial.needsUpdate = true;
|
||||
this.beautyRenderTarget.setSize( width, height );
|
||||
this.prevRenderTarget.setSize( width, height );
|
||||
this.ssrRenderTarget.setSize( width, height );
|
||||
this.normalRenderTarget.setSize( width, height );
|
||||
this.metalnessRenderTarget.setSize( width, height );
|
||||
this.blurRenderTarget.setSize( width, height );
|
||||
this.blurRenderTarget2.setSize( width, height ); // this.blurRenderTarget3.setSize(width, height);
|
||||
|
||||
this.ssrMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
||||
this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
|
||||
this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
||||
this.blurMaterial2.uniforms[ 'resolution' ].value.set( width, height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SSRPass.OUTPUT = {
|
||||
'Default': 0,
|
||||
'SSR': 1,
|
||||
'Beauty': 3,
|
||||
'Depth': 4,
|
||||
'Normal': 5,
|
||||
'Metalness': 7
|
||||
};
|
||||
|
||||
THREE.SSRPass = SSRPass;
|
||||
|
||||
} )();
|
||||
494
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSRrPass.js
generated
vendored
Normal file
494
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SSRrPass.js
generated
vendored
Normal file
@@ -0,0 +1,494 @@
|
||||
( function () {
|
||||
|
||||
class SSRrPass extends THREE.Pass {
|
||||
|
||||
constructor( {
|
||||
renderer,
|
||||
scene,
|
||||
camera,
|
||||
width,
|
||||
height,
|
||||
selects
|
||||
} ) {
|
||||
|
||||
super();
|
||||
this.width = width !== undefined ? width : 512;
|
||||
this.height = height !== undefined ? height : 512;
|
||||
this.clear = true;
|
||||
this.renderer = renderer;
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.output = 0; // this.output = 1;
|
||||
|
||||
this.ior = THREE.SSRrShader.uniforms.ior.value;
|
||||
this.maxDistance = THREE.SSRrShader.uniforms.maxDistance.value;
|
||||
this.surfDist = THREE.SSRrShader.uniforms.surfDist.value;
|
||||
this.tempColor = new THREE.Color();
|
||||
this.selects = selects;
|
||||
this._specular = THREE.SSRrShader.defines.SPECULAR;
|
||||
Object.defineProperty( this, 'specular', {
|
||||
get() {
|
||||
|
||||
return this._specular;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._specular === val ) return;
|
||||
this._specular = val;
|
||||
this.ssrrMaterial.defines.SPECULAR = val;
|
||||
this.ssrrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this._fillHole = THREE.SSRrShader.defines.FILL_HOLE;
|
||||
Object.defineProperty( this, 'fillHole', {
|
||||
get() {
|
||||
|
||||
return this._fillHole;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._fillHole === val ) return;
|
||||
this._fillHole = val;
|
||||
this.ssrrMaterial.defines.FILL_HOLE = val;
|
||||
this.ssrrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this._infiniteThick = THREE.SSRrShader.defines.INFINITE_THICK;
|
||||
Object.defineProperty( this, 'infiniteThick', {
|
||||
get() {
|
||||
|
||||
return this._infiniteThick;
|
||||
|
||||
},
|
||||
|
||||
set( val ) {
|
||||
|
||||
if ( this._infiniteThick === val ) return;
|
||||
this._infiniteThick = val;
|
||||
this.ssrrMaterial.defines.INFINITE_THICK = val;
|
||||
this.ssrrMaterial.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} ); // beauty render target with depth buffer
|
||||
|
||||
const depthTexture = new THREE.DepthTexture();
|
||||
depthTexture.type = THREE.UnsignedShortType;
|
||||
depthTexture.minFilter = THREE.NearestFilter;
|
||||
depthTexture.magFilter = THREE.NearestFilter;
|
||||
this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
depthTexture: depthTexture,
|
||||
depthBuffer: true
|
||||
} );
|
||||
this.specularRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
// TODO: Can merge with refractiveRenderTarget?
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} ); // normalSelects render target
|
||||
|
||||
const depthTextureSelects = new THREE.DepthTexture();
|
||||
depthTextureSelects.type = THREE.UnsignedShortType;
|
||||
depthTextureSelects.minFilter = THREE.NearestFilter;
|
||||
depthTextureSelects.magFilter = THREE.NearestFilter;
|
||||
this.normalSelectsRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.HalfFloatType,
|
||||
depthTexture: depthTextureSelects,
|
||||
depthBuffer: true
|
||||
} ); // refractive render target
|
||||
|
||||
this.refractiveRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} ); // ssrr render target
|
||||
|
||||
this.ssrrRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
format: THREE.RGBAFormat
|
||||
} ); // ssrr material
|
||||
|
||||
if ( THREE.SSRrShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.SSRrPass: The pass relies on THREE.SSRrShader.' );
|
||||
|
||||
}
|
||||
|
||||
this.ssrrMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRrShader.defines, {
|
||||
MAX_STEP: Math.sqrt( this.width * this.width + this.height * this.height )
|
||||
} ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRrShader.uniforms ),
|
||||
vertexShader: THREE.SSRrShader.vertexShader,
|
||||
fragmentShader: THREE.SSRrShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.ssrrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
|
||||
this.ssrrMaterial.uniforms[ 'tNormalSelects' ].value = this.normalSelectsRenderTarget.texture;
|
||||
this.ssrrMaterial.needsUpdate = true;
|
||||
this.ssrrMaterial.uniforms[ 'tRefractive' ].value = this.refractiveRenderTarget.texture;
|
||||
this.ssrrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.ssrrMaterial.uniforms[ 'tDepthSelects' ].value = this.normalSelectsRenderTarget.depthTexture;
|
||||
this.ssrrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.ssrrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
||||
this.ssrrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
|
||||
this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material
|
||||
|
||||
this.normalMaterial = new THREE.MeshNormalMaterial();
|
||||
this.normalMaterial.blending = THREE.NoBlending; // refractiveOn material
|
||||
|
||||
this.refractiveOnMaterial = new THREE.MeshBasicMaterial( {
|
||||
color: 'white'
|
||||
} ); // refractiveOff material
|
||||
|
||||
this.refractiveOffMaterial = new THREE.MeshBasicMaterial( {
|
||||
color: 'black'
|
||||
} ); // specular material
|
||||
|
||||
this.specularMaterial = new THREE.MeshStandardMaterial( {
|
||||
color: 'black',
|
||||
metalness: 0,
|
||||
roughness: .2
|
||||
} ); // material for rendering the depth
|
||||
|
||||
this.depthRenderMaterial = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, THREE.SSRrDepthShader.defines ),
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.SSRrDepthShader.uniforms ),
|
||||
vertexShader: THREE.SSRrDepthShader.vertexShader,
|
||||
fragmentShader: THREE.SSRrDepthShader.fragmentShader,
|
||||
blending: THREE.NoBlending
|
||||
} );
|
||||
this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
||||
this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far; // material for rendering the content of a render target
|
||||
|
||||
this.copyMaterial = new THREE.ShaderMaterial( {
|
||||
uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
|
||||
vertexShader: THREE.CopyShader.vertexShader,
|
||||
fragmentShader: THREE.CopyShader.fragmentShader,
|
||||
transparent: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
blendSrc: THREE.SrcAlphaFactor,
|
||||
blendDst: THREE.OneMinusSrcAlphaFactor,
|
||||
blendEquation: THREE.AddEquation,
|
||||
blendSrcAlpha: THREE.SrcAlphaFactor,
|
||||
blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
|
||||
blendEquationAlpha: THREE.AddEquation // premultipliedAlpha:true,
|
||||
|
||||
} );
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
this.originalClearColor = new THREE.Color();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
// dispose render targets
|
||||
this.beautyRenderTarget.dispose();
|
||||
this.specularRenderTarget.dispose();
|
||||
this.normalSelectsRenderTarget.dispose();
|
||||
this.refractiveRenderTarget.dispose();
|
||||
this.ssrrRenderTarget.dispose(); // dispose materials
|
||||
|
||||
this.normalMaterial.dispose();
|
||||
this.refractiveOnMaterial.dispose();
|
||||
this.refractiveOffMaterial.dispose();
|
||||
this.copyMaterial.dispose();
|
||||
this.depthRenderMaterial.dispose(); // dipsose full screen quad
|
||||
|
||||
this.fsQuad.dispose();
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer
|
||||
/*, readBuffer, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
// render beauty and depth
|
||||
renderer.setRenderTarget( this.beautyRenderTarget );
|
||||
renderer.clear();
|
||||
this.scene.children.forEach( child => {
|
||||
|
||||
if ( this.selects.includes( child ) ) {
|
||||
|
||||
child.visible = false;
|
||||
|
||||
} else {
|
||||
|
||||
child.visible = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
renderer.render( this.scene, this.camera );
|
||||
renderer.setRenderTarget( this.specularRenderTarget );
|
||||
renderer.clear();
|
||||
this.scene.children.forEach( child => {
|
||||
|
||||
if ( this.selects.includes( child ) ) {
|
||||
|
||||
child.visible = true;
|
||||
child._SSRrPassBackupMaterial = child.material;
|
||||
child.material = this.specularMaterial;
|
||||
|
||||
} else if ( ! child.isLight ) {
|
||||
|
||||
child.visible = false;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.children.forEach( child => {
|
||||
|
||||
if ( this.selects.includes( child ) ) {
|
||||
|
||||
child.material = child._SSRrPassBackupMaterial;
|
||||
|
||||
}
|
||||
|
||||
} ); // render normalSelectss
|
||||
|
||||
this.scene.children.forEach( child => {
|
||||
|
||||
if ( this.selects.includes( child ) ) {
|
||||
|
||||
child.visible = true;
|
||||
|
||||
} else {
|
||||
|
||||
child.visible = false;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this.renderOverride( renderer, this.normalMaterial, this.normalSelectsRenderTarget, 0, 0 );
|
||||
this.renderRefractive( renderer, this.refractiveOnMaterial, this.refractiveRenderTarget, 0, 0 ); // render SSRr
|
||||
|
||||
this.ssrrMaterial.uniforms[ 'ior' ].value = this.ior;
|
||||
this.ssrrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
|
||||
this.ssrrMaterial.uniforms[ 'surfDist' ].value = this.surfDist;
|
||||
this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
|
||||
this.renderPass( renderer, this.ssrrMaterial, this.ssrrRenderTarget ); // output result to screen
|
||||
|
||||
switch ( this.output ) {
|
||||
|
||||
case SSRrPass.OUTPUT.Default:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NormalBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.SSRr:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrrRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.Beauty:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.Depth:
|
||||
this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
||||
this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.DepthSelects:
|
||||
this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.normalSelectsRenderTarget.depthTexture;
|
||||
this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.NormalSelects:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalSelectsRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.Refractive:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.refractiveRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
case SSRrPass.OUTPUT.Specular:
|
||||
this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.specularRenderTarget.texture;
|
||||
this.copyMaterial.blending = THREE.NoBlending;
|
||||
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn( 'THREE.SSRrPass: Unknown output type.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
// save original state
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget ); // setup pass state
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = passMaterial;
|
||||
this.fsQuad.render( renderer ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = overrideMaterial;
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.overrideMaterial = null; // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
renderRefractive( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
||||
|
||||
this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
|
||||
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderer.autoClear = false;
|
||||
clearColor = overrideMaterial.clearColor || clearColor;
|
||||
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
||||
|
||||
if ( clearColor !== undefined && clearColor !== null ) {
|
||||
|
||||
renderer.setClearColor( clearColor );
|
||||
renderer.setClearAlpha( clearAlpha || 0.0 );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
this.scene.children.forEach( child => {
|
||||
|
||||
child.visible = true;
|
||||
|
||||
} );
|
||||
this.scene.traverse( child => {
|
||||
|
||||
child._SSRrPassBackupMaterial = child.material;
|
||||
|
||||
if ( this.selects.includes( child ) ) {
|
||||
|
||||
child.material = this.refractiveOnMaterial;
|
||||
|
||||
} else {
|
||||
|
||||
child.material = this.refractiveOffMaterial;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
this.scene._SSRrPassBackupBackground = this.scene.background;
|
||||
this.scene.background = null;
|
||||
this.scene._SSRrPassBackupFog = this.scene.fog;
|
||||
this.scene.fog = null;
|
||||
renderer.render( this.scene, this.camera );
|
||||
this.scene.fog = this.scene._SSRrPassBackupFog;
|
||||
this.scene.background = this.scene._SSRrPassBackupBackground;
|
||||
this.scene.traverse( child => {
|
||||
|
||||
child.material = child._SSRrPassBackupMaterial;
|
||||
|
||||
} ); // restore original state
|
||||
|
||||
renderer.autoClear = originalAutoClear;
|
||||
renderer.setClearColor( this.originalClearColor );
|
||||
renderer.setClearAlpha( originalClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.ssrrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
|
||||
this.ssrrMaterial.needsUpdate = true;
|
||||
this.beautyRenderTarget.setSize( width, height );
|
||||
this.specularRenderTarget.setSize( width, height );
|
||||
this.ssrrRenderTarget.setSize( width, height );
|
||||
this.normalSelectsRenderTarget.setSize( width, height );
|
||||
this.refractiveRenderTarget.setSize( width, height );
|
||||
this.ssrrMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
||||
this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
||||
this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SSRrPass.OUTPUT = {
|
||||
'Default': 0,
|
||||
'SSRr': 1,
|
||||
'Beauty': 3,
|
||||
'Depth': 4,
|
||||
'DepthSelects': 9,
|
||||
'NormalSelects': 5,
|
||||
'Refractive': 7,
|
||||
'Specular': 8
|
||||
};
|
||||
|
||||
THREE.SSRrPass = SSRrPass;
|
||||
|
||||
} )();
|
||||
51
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SavePass.js
generated
vendored
Normal file
51
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/SavePass.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
( function () {
|
||||
|
||||
class SavePass extends THREE.Pass {
|
||||
|
||||
constructor( renderTarget ) {
|
||||
|
||||
super();
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.SavePass relies on THREE.CopyShader' );
|
||||
const shader = THREE.CopyShader;
|
||||
this.textureID = 'tDiffuse';
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
} );
|
||||
this.renderTarget = renderTarget;
|
||||
|
||||
if ( this.renderTarget === undefined ) {
|
||||
|
||||
this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
|
||||
this.renderTarget.texture.name = 'SavePass.rt';
|
||||
|
||||
}
|
||||
|
||||
this.needsSwap = false;
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
if ( this.uniforms[ this.textureID ] ) {
|
||||
|
||||
this.uniforms[ this.textureID ].value = readBuffer.texture;
|
||||
|
||||
}
|
||||
|
||||
renderer.setRenderTarget( this.renderTarget );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.SavePass = SavePass;
|
||||
|
||||
} )();
|
||||
63
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/ShaderPass.js
generated
vendored
Normal file
63
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/ShaderPass.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
( function () {
|
||||
|
||||
class ShaderPass extends THREE.Pass {
|
||||
|
||||
constructor( shader, textureID ) {
|
||||
|
||||
super();
|
||||
this.textureID = textureID !== undefined ? textureID : 'tDiffuse';
|
||||
|
||||
if ( shader instanceof THREE.ShaderMaterial ) {
|
||||
|
||||
this.uniforms = shader.uniforms;
|
||||
this.material = shader;
|
||||
|
||||
} else if ( shader ) {
|
||||
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
defines: Object.assign( {}, shader.defines ),
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad = new THREE.FullScreenQuad( this.material );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
if ( this.uniforms[ this.textureID ] ) {
|
||||
|
||||
this.uniforms[ this.textureID ].value = readBuffer.texture;
|
||||
|
||||
}
|
||||
|
||||
this.fsQuad.material = this.material;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( writeBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
|
||||
|
||||
if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.ShaderPass = ShaderPass;
|
||||
|
||||
} )();
|
||||
128
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/TAARenderPass.js
generated
vendored
Normal file
128
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/TAARenderPass.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
*
|
||||
* Temporal Anti-Aliasing Render Pass
|
||||
*
|
||||
* When there is no motion in the scene, the TAA render pass accumulates jittered camera samples across frames to create a high quality anti-aliased result.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* TODO: Add support for motion vector pas so that accumulation of samples across frames can occur on dynamics scenes.
|
||||
*
|
||||
*/
|
||||
|
||||
class TAARenderPass extends THREE.SSAARenderPass {
|
||||
|
||||
constructor( scene, camera, clearColor, clearAlpha ) {
|
||||
|
||||
super( scene, camera, clearColor, clearAlpha );
|
||||
this.sampleLevel = 0;
|
||||
this.accumulate = false;
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime ) {
|
||||
|
||||
if ( this.accumulate === false ) {
|
||||
|
||||
super.render( renderer, writeBuffer, readBuffer, deltaTime );
|
||||
this.accumulateIndex = - 1;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const jitterOffsets = _JitterVectors[ 5 ];
|
||||
|
||||
if ( this.sampleRenderTarget === undefined ) {
|
||||
|
||||
this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
|
||||
this.sampleRenderTarget.texture.name = 'TAARenderPass.sample';
|
||||
|
||||
}
|
||||
|
||||
if ( this.holdRenderTarget === undefined ) {
|
||||
|
||||
this.holdRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
|
||||
this.holdRenderTarget.texture.name = 'TAARenderPass.hold';
|
||||
|
||||
}
|
||||
|
||||
if ( this.accumulateIndex === - 1 ) {
|
||||
|
||||
super.render( renderer, this.holdRenderTarget, readBuffer, deltaTime );
|
||||
this.accumulateIndex = 0;
|
||||
|
||||
}
|
||||
|
||||
const autoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
const sampleWeight = 1.0 / jitterOffsets.length;
|
||||
|
||||
if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
|
||||
|
||||
this.copyUniforms[ 'opacity' ].value = sampleWeight;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = writeBuffer.texture; // render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
|
||||
|
||||
const numSamplesPerFrame = Math.pow( 2, this.sampleLevel );
|
||||
|
||||
for ( let i = 0; i < numSamplesPerFrame; i ++ ) {
|
||||
|
||||
const j = this.accumulateIndex;
|
||||
const jitterOffset = jitterOffsets[ j ];
|
||||
|
||||
if ( this.camera.setViewOffset ) {
|
||||
|
||||
this.camera.setViewOffset( readBuffer.width, readBuffer.height, jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
|
||||
readBuffer.width, readBuffer.height );
|
||||
|
||||
}
|
||||
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
renderer.clear();
|
||||
renderer.render( this.scene, this.camera );
|
||||
renderer.setRenderTarget( this.sampleRenderTarget );
|
||||
if ( this.accumulateIndex === 0 ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
this.accumulateIndex ++;
|
||||
if ( this.accumulateIndex >= jitterOffsets.length ) break;
|
||||
|
||||
}
|
||||
|
||||
if ( this.camera.clearViewOffset ) this.camera.clearViewOffset();
|
||||
|
||||
}
|
||||
|
||||
const accumulationWeight = this.accumulateIndex * sampleWeight;
|
||||
|
||||
if ( accumulationWeight > 0 ) {
|
||||
|
||||
this.copyUniforms[ 'opacity' ].value = 1.0;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.sampleRenderTarget.texture;
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
if ( accumulationWeight < 1.0 ) {
|
||||
|
||||
this.copyUniforms[ 'opacity' ].value = 1.0 - accumulationWeight;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.holdRenderTarget.texture;
|
||||
renderer.setRenderTarget( writeBuffer );
|
||||
if ( accumulationWeight === 0 ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
renderer.autoClear = autoClear;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const _JitterVectors = [[[ 0, 0 ]], [[ 4, 4 ], [ - 4, - 4 ]], [[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]], [[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ], [ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]], [[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ], [ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ], [ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ], [ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]], [[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ], [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ], [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ], [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ], [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ], [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ], [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ], [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]]];
|
||||
|
||||
THREE.TAARenderPass = TAARenderPass;
|
||||
|
||||
} )();
|
||||
46
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/TexturePass.js
generated
vendored
Normal file
46
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/TexturePass.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
( function () {
|
||||
|
||||
class TexturePass extends THREE.Pass {
|
||||
|
||||
constructor( map, opacity ) {
|
||||
|
||||
super();
|
||||
if ( THREE.CopyShader === undefined ) console.error( 'THREE.TexturePass relies on THREE.CopyShader' );
|
||||
const shader = THREE.CopyShader;
|
||||
this.map = map;
|
||||
this.opacity = opacity !== undefined ? opacity : 1.0;
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
} );
|
||||
this.needsSwap = false;
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer
|
||||
/*, deltaTime, maskActive */
|
||||
) {
|
||||
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
this.fsQuad.material = this.material;
|
||||
this.uniforms[ 'opacity' ].value = this.opacity;
|
||||
this.uniforms[ 'tDiffuse' ].value = this.map;
|
||||
this.material.transparent = this.opacity < 1.0;
|
||||
renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
|
||||
if ( this.clear ) renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THREE.TexturePass = TexturePass;
|
||||
|
||||
} )();
|
||||
366
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/UnrealBloomPass.js
generated
vendored
Normal file
366
HTML/ThreeJS/node_modules/three/examples/js/postprocessing/UnrealBloomPass.js
generated
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
( function () {
|
||||
|
||||
/**
|
||||
* UnrealBloomPass is inspired by the bloom pass of Unreal Engine. It creates a
|
||||
* mip map chain of bloom textures and blurs them with different radii. Because
|
||||
* of the weighted combination of mips, and because larger blurs are done on
|
||||
* higher mips, this effect provides good quality and performance.
|
||||
*
|
||||
* Reference:
|
||||
* - https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/
|
||||
*/
|
||||
|
||||
class UnrealBloomPass extends THREE.Pass {
|
||||
|
||||
constructor( resolution, strength, radius, threshold ) {
|
||||
|
||||
super();
|
||||
this.strength = strength !== undefined ? strength : 1;
|
||||
this.radius = radius;
|
||||
this.threshold = threshold;
|
||||
this.resolution = resolution !== undefined ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 ); // create color only once here, reuse it later inside the render function
|
||||
|
||||
this.clearColor = new THREE.Color( 0, 0, 0 ); // render targets
|
||||
|
||||
const pars = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat
|
||||
};
|
||||
this.renderTargetsHorizontal = [];
|
||||
this.renderTargetsVertical = [];
|
||||
this.nMips = 5;
|
||||
let resx = Math.round( this.resolution.x / 2 );
|
||||
let resy = Math.round( this.resolution.y / 2 );
|
||||
this.renderTargetBright = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetBright.texture.name = 'UnrealBloomPass.bright';
|
||||
this.renderTargetBright.texture.generateMipmaps = false;
|
||||
|
||||
for ( let i = 0; i < this.nMips; i ++ ) {
|
||||
|
||||
const renderTargetHorizonal = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
renderTargetHorizonal.texture.name = 'UnrealBloomPass.h' + i;
|
||||
renderTargetHorizonal.texture.generateMipmaps = false;
|
||||
this.renderTargetsHorizontal.push( renderTargetHorizonal );
|
||||
const renderTargetVertical = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
renderTargetVertical.texture.name = 'UnrealBloomPass.v' + i;
|
||||
renderTargetVertical.texture.generateMipmaps = false;
|
||||
this.renderTargetsVertical.push( renderTargetVertical );
|
||||
resx = Math.round( resx / 2 );
|
||||
resy = Math.round( resy / 2 );
|
||||
|
||||
} // luminosity high pass material
|
||||
|
||||
|
||||
if ( THREE.LuminosityHighPassShader === undefined ) console.error( 'THREE.UnrealBloomPass relies on THREE.LuminosityHighPassShader' );
|
||||
const highPassShader = THREE.LuminosityHighPassShader;
|
||||
this.highPassUniforms = THREE.UniformsUtils.clone( highPassShader.uniforms );
|
||||
this.highPassUniforms[ 'luminosityThreshold' ].value = threshold;
|
||||
this.highPassUniforms[ 'smoothWidth' ].value = 0.01;
|
||||
this.materialHighPassFilter = new THREE.ShaderMaterial( {
|
||||
uniforms: this.highPassUniforms,
|
||||
vertexShader: highPassShader.vertexShader,
|
||||
fragmentShader: highPassShader.fragmentShader,
|
||||
defines: {}
|
||||
} ); // Gaussian Blur Materials
|
||||
|
||||
this.separableBlurMaterials = [];
|
||||
const kernelSizeArray = [ 3, 5, 7, 9, 11 ];
|
||||
resx = Math.round( this.resolution.x / 2 );
|
||||
resy = Math.round( this.resolution.y / 2 );
|
||||
|
||||
for ( let i = 0; i < this.nMips; i ++ ) {
|
||||
|
||||
this.separableBlurMaterials.push( this.getSeperableBlurMaterial( kernelSizeArray[ i ] ) );
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'texSize' ].value = new THREE.Vector2( resx, resy );
|
||||
resx = Math.round( resx / 2 );
|
||||
resy = Math.round( resy / 2 );
|
||||
|
||||
} // Composite material
|
||||
|
||||
|
||||
this.compositeMaterial = this.getCompositeMaterial( this.nMips );
|
||||
this.compositeMaterial.uniforms[ 'blurTexture1' ].value = this.renderTargetsVertical[ 0 ].texture;
|
||||
this.compositeMaterial.uniforms[ 'blurTexture2' ].value = this.renderTargetsVertical[ 1 ].texture;
|
||||
this.compositeMaterial.uniforms[ 'blurTexture3' ].value = this.renderTargetsVertical[ 2 ].texture;
|
||||
this.compositeMaterial.uniforms[ 'blurTexture4' ].value = this.renderTargetsVertical[ 3 ].texture;
|
||||
this.compositeMaterial.uniforms[ 'blurTexture5' ].value = this.renderTargetsVertical[ 4 ].texture;
|
||||
this.compositeMaterial.uniforms[ 'bloomStrength' ].value = strength;
|
||||
this.compositeMaterial.uniforms[ 'bloomRadius' ].value = 0.1;
|
||||
this.compositeMaterial.needsUpdate = true;
|
||||
const bloomFactors = [ 1.0, 0.8, 0.6, 0.4, 0.2 ];
|
||||
this.compositeMaterial.uniforms[ 'bloomFactors' ].value = bloomFactors;
|
||||
this.bloomTintColors = [ new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ) ];
|
||||
this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors; // copy material
|
||||
|
||||
if ( THREE.CopyShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.UnrealBloomPass relies on THREE.CopyShader' );
|
||||
|
||||
}
|
||||
|
||||
const copyShader = THREE.CopyShader;
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.copyUniforms[ 'opacity' ].value = 1.0;
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
blending: THREE.AdditiveBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
transparent: true
|
||||
} );
|
||||
this.enabled = true;
|
||||
this.needsSwap = false;
|
||||
this._oldClearColor = new THREE.Color();
|
||||
this.oldClearAlpha = 1;
|
||||
this.basic = new THREE.MeshBasicMaterial();
|
||||
this.fsQuad = new THREE.FullScreenQuad( null );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
for ( let i = 0; i < this.renderTargetsHorizontal.length; i ++ ) {
|
||||
|
||||
this.renderTargetsHorizontal[ i ].dispose();
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < this.renderTargetsVertical.length; i ++ ) {
|
||||
|
||||
this.renderTargetsVertical[ i ].dispose();
|
||||
|
||||
}
|
||||
|
||||
this.renderTargetBright.dispose();
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
let resx = Math.round( width / 2 );
|
||||
let resy = Math.round( height / 2 );
|
||||
this.renderTargetBright.setSize( resx, resy );
|
||||
|
||||
for ( let i = 0; i < this.nMips; i ++ ) {
|
||||
|
||||
this.renderTargetsHorizontal[ i ].setSize( resx, resy );
|
||||
this.renderTargetsVertical[ i ].setSize( resx, resy );
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'texSize' ].value = new THREE.Vector2( resx, resy );
|
||||
resx = Math.round( resx / 2 );
|
||||
resy = Math.round( resy / 2 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
|
||||
|
||||
renderer.getClearColor( this._oldClearColor );
|
||||
this.oldClearAlpha = renderer.getClearAlpha();
|
||||
const oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
renderer.setClearColor( this.clearColor, 0 );
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); // Render input to screen
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
this.fsQuad.material = this.basic;
|
||||
this.basic.map = readBuffer.texture;
|
||||
renderer.setRenderTarget( null );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} // 1. Extract Bright Areas
|
||||
|
||||
|
||||
this.highPassUniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
||||
this.highPassUniforms[ 'luminosityThreshold' ].value = this.threshold;
|
||||
this.fsQuad.material = this.materialHighPassFilter;
|
||||
renderer.setRenderTarget( this.renderTargetBright );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // 2. Blur All the mips progressively
|
||||
|
||||
let inputRenderTarget = this.renderTargetBright;
|
||||
|
||||
for ( let i = 0; i < this.nMips; i ++ ) {
|
||||
|
||||
this.fsQuad.material = this.separableBlurMaterials[ i ];
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = inputRenderTarget.texture;
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionX;
|
||||
renderer.setRenderTarget( this.renderTargetsHorizontal[ i ] );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = this.renderTargetsHorizontal[ i ].texture;
|
||||
this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionY;
|
||||
renderer.setRenderTarget( this.renderTargetsVertical[ i ] );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer );
|
||||
inputRenderTarget = this.renderTargetsVertical[ i ];
|
||||
|
||||
} // Composite All the mips
|
||||
|
||||
|
||||
this.fsQuad.material = this.compositeMaterial;
|
||||
this.compositeMaterial.uniforms[ 'bloomStrength' ].value = this.strength;
|
||||
this.compositeMaterial.uniforms[ 'bloomRadius' ].value = this.radius;
|
||||
this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors;
|
||||
renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] );
|
||||
renderer.clear();
|
||||
this.fsQuad.render( renderer ); // Blend it additively over the input texture
|
||||
|
||||
this.fsQuad.material = this.materialCopy;
|
||||
this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetsHorizontal[ 0 ].texture;
|
||||
if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( readBuffer );
|
||||
this.fsQuad.render( renderer );
|
||||
|
||||
} // Restore renderer settings
|
||||
|
||||
|
||||
renderer.setClearColor( this._oldClearColor, this.oldClearAlpha );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
getSeperableBlurMaterial( kernelRadius ) {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
defines: {
|
||||
'KERNEL_RADIUS': kernelRadius,
|
||||
'SIGMA': kernelRadius
|
||||
},
|
||||
uniforms: {
|
||||
'colorTexture': {
|
||||
value: null
|
||||
},
|
||||
'texSize': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
},
|
||||
'direction': {
|
||||
value: new THREE.Vector2( 0.5, 0.5 )
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: `#include <common>
|
||||
varying vec2 vUv;
|
||||
uniform sampler2D colorTexture;
|
||||
uniform vec2 texSize;
|
||||
uniform vec2 direction;
|
||||
|
||||
float gaussianPdf(in float x, in float sigma) {
|
||||
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
|
||||
}
|
||||
void main() {
|
||||
vec2 invSize = 1.0 / texSize;
|
||||
float fSigma = float(SIGMA);
|
||||
float weightSum = gaussianPdf(0.0, fSigma);
|
||||
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;
|
||||
for( int i = 1; i < KERNEL_RADIUS; i ++ ) {
|
||||
float x = float(i);
|
||||
float w = gaussianPdf(x, fSigma);
|
||||
vec2 uvOffset = direction * invSize * x;
|
||||
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;
|
||||
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;
|
||||
diffuseSum += (sample1 + sample2) * w;
|
||||
weightSum += 2.0 * w;
|
||||
}
|
||||
gl_FragColor = vec4(diffuseSum/weightSum, 1.0);
|
||||
}`
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
getCompositeMaterial( nMips ) {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
defines: {
|
||||
'NUM_MIPS': nMips
|
||||
},
|
||||
uniforms: {
|
||||
'blurTexture1': {
|
||||
value: null
|
||||
},
|
||||
'blurTexture2': {
|
||||
value: null
|
||||
},
|
||||
'blurTexture3': {
|
||||
value: null
|
||||
},
|
||||
'blurTexture4': {
|
||||
value: null
|
||||
},
|
||||
'blurTexture5': {
|
||||
value: null
|
||||
},
|
||||
'dirtTexture': {
|
||||
value: null
|
||||
},
|
||||
'bloomStrength': {
|
||||
value: 1.0
|
||||
},
|
||||
'bloomFactors': {
|
||||
value: null
|
||||
},
|
||||
'bloomTintColors': {
|
||||
value: null
|
||||
},
|
||||
'bloomRadius': {
|
||||
value: 0.0
|
||||
}
|
||||
},
|
||||
vertexShader: `varying vec2 vUv;
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: `varying vec2 vUv;
|
||||
uniform sampler2D blurTexture1;
|
||||
uniform sampler2D blurTexture2;
|
||||
uniform sampler2D blurTexture3;
|
||||
uniform sampler2D blurTexture4;
|
||||
uniform sampler2D blurTexture5;
|
||||
uniform sampler2D dirtTexture;
|
||||
uniform float bloomStrength;
|
||||
uniform float bloomRadius;
|
||||
uniform float bloomFactors[NUM_MIPS];
|
||||
uniform vec3 bloomTintColors[NUM_MIPS];
|
||||
|
||||
float lerpBloomFactor(const in float factor) {
|
||||
float mirrorFactor = 1.2 - factor;
|
||||
return mix(factor, mirrorFactor, bloomRadius);
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = bloomStrength * ( lerpBloomFactor(bloomFactors[0]) * vec4(bloomTintColors[0], 1.0) * texture2D(blurTexture1, vUv) +
|
||||
lerpBloomFactor(bloomFactors[1]) * vec4(bloomTintColors[1], 1.0) * texture2D(blurTexture2, vUv) +
|
||||
lerpBloomFactor(bloomFactors[2]) * vec4(bloomTintColors[2], 1.0) * texture2D(blurTexture3, vUv) +
|
||||
lerpBloomFactor(bloomFactors[3]) * vec4(bloomTintColors[3], 1.0) * texture2D(blurTexture4, vUv) +
|
||||
lerpBloomFactor(bloomFactors[4]) * vec4(bloomTintColors[4], 1.0) * texture2D(blurTexture5, vUv) );
|
||||
}`
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
|
||||
UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );
|
||||
|
||||
THREE.UnrealBloomPass = UnrealBloomPass;
|
||||
|
||||
} )();
|
||||
Reference in New Issue
Block a user