1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-05 10:49:36 +02:00
Daniel Neto 2023-12-11 11:59:56 -03:00
parent f0f62670c5
commit 7e26256cac
4563 changed files with 1246712 additions and 17558 deletions

372
node_modules/three/examples/js/objects/Lensflare.js generated vendored Normal file
View file

@ -0,0 +1,372 @@
THREE.Lensflare = function () {
THREE.Mesh.call( this, THREE.Lensflare.Geometry, new THREE.MeshBasicMaterial( { opacity: 0, transparent: true } ) );
this.type = 'Lensflare';
this.frustumCulled = false;
this.renderOrder = Infinity;
//
var positionScreen = new THREE.Vector3();
var positionView = new THREE.Vector3();
// textures
var tempMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
tempMap.minFilter = THREE.NearestFilter;
tempMap.magFilter = THREE.NearestFilter;
tempMap.wrapS = THREE.ClampToEdgeWrapping;
tempMap.wrapT = THREE.ClampToEdgeWrapping;
var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
occlusionMap.minFilter = THREE.NearestFilter;
occlusionMap.magFilter = THREE.NearestFilter;
occlusionMap.wrapS = THREE.ClampToEdgeWrapping;
occlusionMap.wrapT = THREE.ClampToEdgeWrapping;
// material
var geometry = THREE.Lensflare.Geometry;
var material1a = new THREE.RawShaderMaterial( {
uniforms: {
'scale': { value: null },
'screenPosition': { value: null }
},
vertexShader: [
'precision highp float;',
'uniform vec3 screenPosition;',
'uniform vec2 scale;',
'attribute vec3 position;',
'void main() {',
' gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );',
'}'
].join( '\n' ),
fragmentShader: [
'precision highp float;',
'void main() {',
' gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );',
'}'
].join( '\n' ),
depthTest: true,
depthWrite: false,
transparent: false
} );
var material1b = new THREE.RawShaderMaterial( {
uniforms: {
'map': { value: tempMap },
'scale': { value: null },
'screenPosition': { value: null }
},
vertexShader: [
'precision highp float;',
'uniform vec3 screenPosition;',
'uniform vec2 scale;',
'attribute vec3 position;',
'attribute vec2 uv;',
'varying vec2 vUV;',
'void main() {',
' vUV = uv;',
' gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );',
'}'
].join( '\n' ),
fragmentShader: [
'precision highp float;',
'uniform sampler2D map;',
'varying vec2 vUV;',
'void main() {',
' gl_FragColor = texture2D( map, vUV );',
'}'
].join( '\n' ),
depthTest: false,
depthWrite: false,
transparent: false
} );
// the following object is used for occlusionMap generation
var mesh1 = new THREE.Mesh( geometry, material1a );
//
var elements = [];
var shader = THREE.LensflareElement.Shader;
var material2 = new THREE.RawShaderMaterial( {
uniforms: {
'map': { value: null },
'occlusionMap': { value: occlusionMap },
'color': { value: new THREE.Color( 0xffffff ) },
'scale': { value: new THREE.Vector2() },
'screenPosition': { value: new THREE.Vector3() }
},
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
blending: THREE.AdditiveBlending,
transparent: true,
depthWrite: false
} );
var mesh2 = new THREE.Mesh( geometry, material2 );
this.addElement = function ( element ) {
elements.push( element );
};
//
var scale = new THREE.Vector2();
var screenPositionPixels = new THREE.Vector2();
var validArea = new THREE.Box2();
var viewport = new THREE.Vector4();
this.onBeforeRender = function ( renderer, scene, camera ) {
renderer.getCurrentViewport( viewport );
var invAspect = viewport.w / viewport.z;
var halfViewportWidth = viewport.z / 2.0;
var halfViewportHeight = viewport.w / 2.0;
var size = 16 / viewport.w;
scale.set( size * invAspect, size );
validArea.min.set( viewport.x, viewport.y );
validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );
// calculate position in screen space
positionView.setFromMatrixPosition( this.matrixWorld );
positionView.applyMatrix4( camera.matrixWorldInverse );
if ( positionView.z > 0 ) return; // lensflare is behind the camera
positionScreen.copy( positionView ).applyMatrix4( camera.projectionMatrix );
// horizontal and vertical coordinate of the lower left corner of the pixels to copy
screenPositionPixels.x = viewport.x + ( positionScreen.x * halfViewportWidth ) + halfViewportWidth - 8;
screenPositionPixels.y = viewport.y + ( positionScreen.y * halfViewportHeight ) + halfViewportHeight - 8;
// screen cull
if ( validArea.containsPoint( screenPositionPixels ) ) {
// save current RGB to temp texture
renderer.copyFramebufferToTexture( screenPositionPixels, tempMap );
// render pink quad
var uniforms = material1a.uniforms;
uniforms[ 'scale' ].value = scale;
uniforms[ 'screenPosition' ].value = positionScreen;
renderer.renderBufferDirect( camera, null, geometry, material1a, mesh1, null );
// copy result to occlusionMap
renderer.copyFramebufferToTexture( screenPositionPixels, occlusionMap );
// restore graphics
var uniforms = material1b.uniforms;
uniforms[ 'scale' ].value = scale;
uniforms[ 'screenPosition' ].value = positionScreen;
renderer.renderBufferDirect( camera, null, geometry, material1b, mesh1, null );
// render elements
var vecX = - positionScreen.x * 2;
var vecY = - positionScreen.y * 2;
for ( var i = 0, l = elements.length; i < l; i ++ ) {
var element = elements[ i ];
var uniforms = material2.uniforms;
uniforms[ 'color' ].value.copy( element.color );
uniforms[ 'map' ].value = element.texture;
uniforms[ 'screenPosition' ].value.x = positionScreen.x + vecX * element.distance;
uniforms[ 'screenPosition' ].value.y = positionScreen.y + vecY * element.distance;
var size = element.size / viewport.w;
var invAspect = viewport.w / viewport.z;
uniforms[ 'scale' ].value.set( size * invAspect, size );
material2.uniformsNeedUpdate = true;
renderer.renderBufferDirect( camera, null, geometry, material2, mesh2, null );
}
}
};
this.dispose = function () {
material1a.dispose();
material1b.dispose();
material2.dispose();
tempMap.dispose();
occlusionMap.dispose();
for ( var i = 0, l = elements.length; i < l; i ++ ) {
elements[ i ].texture.dispose();
}
};
};
THREE.Lensflare.prototype = Object.create( THREE.Mesh.prototype );
THREE.Lensflare.prototype.constructor = THREE.Lensflare;
THREE.Lensflare.prototype.isLensflare = true;
//
THREE.LensflareElement = function ( texture, size, distance, color ) {
this.texture = texture;
this.size = size || 1;
this.distance = distance || 0;
this.color = color || new THREE.Color( 0xffffff );
};
THREE.LensflareElement.Shader = {
uniforms: {
'map': { value: null },
'occlusionMap': { value: null },
'color': { value: null },
'scale': { value: null },
'screenPosition': { value: null }
},
vertexShader: [
'precision highp float;',
'uniform vec3 screenPosition;',
'uniform vec2 scale;',
'uniform sampler2D occlusionMap;',
'attribute vec3 position;',
'attribute vec2 uv;',
'varying vec2 vUV;',
'varying float vVisibility;',
'void main() {',
' vUV = uv;',
' vec2 pos = position.xy;',
' vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );',
' visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );',
' vVisibility = visibility.r / 9.0;',
' vVisibility *= 1.0 - visibility.g / 9.0;',
' vVisibility *= visibility.b / 9.0;',
' gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );',
'}'
].join( '\n' ),
fragmentShader: [
'precision highp float;',
'uniform sampler2D map;',
'uniform vec3 color;',
'varying vec2 vUV;',
'varying float vVisibility;',
'void main() {',
' vec4 texture = texture2D( map, vUV );',
' texture.a *= vVisibility;',
' gl_FragColor = texture;',
' gl_FragColor.rgb *= color;',
'}'
].join( '\n' )
};
THREE.Lensflare.Geometry = ( function () {
var geometry = new THREE.BufferGeometry();
var float32Array = new Float32Array( [
- 1, - 1, 0, 0, 0,
1, - 1, 0, 1, 0,
1, 1, 0, 1, 1,
- 1, 1, 0, 0, 1
] );
var interleavedBuffer = new THREE.InterleavedBuffer( float32Array, 5 );
geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
geometry.setAttribute( 'position', new THREE.InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
geometry.setAttribute( 'uv', new THREE.InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
return geometry;
} )();

View file

@ -0,0 +1,236 @@
/**
* @fileoverview Lightning strike object generator
*
*
* Usage
*
* var myStorm = new THREE.LightningStorm( paramsObject );
* myStorm.position.set( ... );
* scene.add( myStorm );
* ...
* myStorm.update( currentTime );
*
* The "currentTime" can only go forwards or be stopped.
*
*
* LightningStorm parameters:
*
* @param {double} size Size of the storm. If no 'onRayPosition' parameter is defined, it means the side of the rectangle the storm covers.
*
* @param {double} minHeight Minimum height a ray can start at. If no 'onRayPosition' parameter is defined, it means the height above plane y = 0.
*
* @param {double} maxHeight Maximum height a ray can start at. If no 'onRayPosition' parameter is defined, it means the height above plane y = 0.
*
* @param {double} maxSlope The maximum inclination slope of a ray. If no 'onRayPosition' parameter is defined, it means the slope relative to plane y = 0.
*
* @param {integer} maxLightnings Greater than 0. The maximum number of simultaneous rays.
*
* @param {double} lightningMinPeriod minimum time between two consecutive rays.
*
* @param {double} lightningMaxPeriod maximum time between two consecutive rays.
*
* @param {double} lightningMinDuration The minimum time a ray can last.
*
* @param {double} lightningMaxDuration The maximum time a ray can last.
*
* @param {Object} lightningParameters The parameters for created rays. See THREE.LightningStrike (geometry)
*
* @param {Material} lightningMaterial The THREE.Material used for the created rays.
*
* @param {function} onRayPosition Optional callback with two Vector3 parameters (source, dest). You can set here the start and end points for each created ray, using the standard size, minHeight, etc parameters and other values in your algorithm.
*
* @param {function} onLightningDown This optional callback is called with one parameter (lightningStrike) when a ray ends propagating, so it has hit the ground.
*
*
*/
THREE.LightningStorm = function ( stormParams ) {
THREE.Object3D.call( this );
// Parameters
stormParams = stormParams || {};
this.stormParams = stormParams;
stormParams.size = stormParams.size !== undefined ? stormParams.size : 1000.0;
stormParams.minHeight = stormParams.minHeight !== undefined ? stormParams.minHeight : 80.0;
stormParams.maxHeight = stormParams.maxHeight !== undefined ? stormParams.maxHeight : 100.0;
stormParams.maxSlope = stormParams.maxSlope !== undefined ? stormParams.maxSlope : 1.1;
stormParams.maxLightnings = stormParams.maxLightnings !== undefined ? stormParams.maxLightnings : 3;
stormParams.lightningMinPeriod = stormParams.lightningMinPeriod !== undefined ? stormParams.lightningMinPeriod : 3.0;
stormParams.lightningMaxPeriod = stormParams.lightningMaxPeriod !== undefined ? stormParams.lightningMaxPeriod : 7.0;
stormParams.lightningMinDuration = stormParams.lightningMinDuration !== undefined ? stormParams.lightningMinDuration : 1.0;
stormParams.lightningMaxDuration = stormParams.lightningMaxDuration !== undefined ? stormParams.lightningMaxDuration : 2.5;
this.lightningParameters = THREE.LightningStrike.copyParameters( stormParams.lightningParameters, stormParams.lightningParameters );
this.lightningParameters.isEternal = false;
this.lightningMaterial = stormParams.lightningMaterial !== undefined ? stormParams.lightningMaterial : new THREE.MeshBasicMaterial( { color: 0xB0FFFF } );
if ( stormParams.onRayPosition !== undefined ) {
this.onRayPosition = stormParams.onRayPosition;
} else {
this.onRayPosition = function ( source, dest ) {
dest.set( ( Math.random() - 0.5 ) * stormParams.size, 0, ( Math.random() - 0.5 ) * stormParams.size );
var height = THREE.MathUtils.lerp( stormParams.minHeight, stormParams.maxHeight, Math.random() );
source.set( stormParams.maxSlope * ( 2 * Math.random() - 1 ), 1, stormParams.maxSlope * ( 2 * Math.random() - 1 ) ).multiplyScalar( height ).add( dest );
};
}
this.onLightningDown = stormParams.onLightningDown;
// Internal state
this.inited = false;
this.nextLightningTime = 0;
this.lightningsMeshes = [];
this.deadLightningsMeshes = [];
for ( var i = 0; i < this.stormParams.maxLightnings; i ++ ) {
var lightning = new THREE.LightningStrike( THREE.LightningStrike.copyParameters( {}, this.lightningParameters ) );
var mesh = new THREE.Mesh( lightning, this.lightningMaterial );
this.deadLightningsMeshes.push( mesh );
}
};
THREE.LightningStorm.prototype = Object.create( THREE.Object3D.prototype );
THREE.LightningStorm.prototype.constructor = THREE.LightningStorm;
THREE.LightningStorm.prototype.isLightningStorm = true;
THREE.LightningStorm.prototype.update = function ( time ) {
if ( ! this.inited ) {
this.nextLightningTime = this.getNextLightningTime( time ) * Math.random();
this.inited = true;
}
if ( time >= this.nextLightningTime ) {
// Lightning creation
var lightningMesh = this.deadLightningsMeshes.pop();
if ( lightningMesh ) {
var lightningParams1 = THREE.LightningStrike.copyParameters( lightningMesh.geometry.rayParameters, this.lightningParameters );
lightningParams1.birthTime = time;
lightningParams1.deathTime = time + THREE.MathUtils.lerp( this.stormParams.lightningMinDuration, this.stormParams.lightningMaxDuration, Math.random() );
this.onRayPosition( lightningParams1.sourceOffset, lightningParams1.destOffset );
lightningParams1.noiseSeed = Math.random();
this.add( lightningMesh );
this.lightningsMeshes.push( lightningMesh );
}
// Schedule next lightning
this.nextLightningTime = this.getNextLightningTime( time );
}
var i = 0, il = this.lightningsMeshes.length;
while ( i < il ) {
var mesh = this.lightningsMeshes[ i ];
var lightning = mesh.geometry;
var prevState = lightning.state;
lightning.update( time );
if ( prevState === THREE.LightningStrike.RAY_PROPAGATING && lightning.state > prevState ) {
if ( this.onLightningDown ) {
this.onLightningDown( lightning );
}
}
if ( lightning.state === THREE.LightningStrike.RAY_EXTINGUISHED ) {
// Lightning is to be destroyed
this.lightningsMeshes.splice( this.lightningsMeshes.indexOf( mesh ), 1 );
this.deadLightningsMeshes.push( mesh );
this.remove( mesh );
il --;
} else {
i ++;
}
}
};
THREE.LightningStorm.prototype.getNextLightningTime = function ( currentTime ) {
return currentTime + THREE.MathUtils.lerp( this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random() ) / ( this.stormParams.maxLightnings + 1 );
};
THREE.LightningStorm.prototype.copy = function ( source ) {
THREE.Object3D.prototype.copy.call( this, source );
this.stormParams.size = source.stormParams.size;
this.stormParams.minHeight = source.stormParams.minHeight;
this.stormParams.maxHeight = source.stormParams.maxHeight;
this.stormParams.maxSlope = source.stormParams.maxSlope;
this.stormParams.maxLightnings = source.stormParams.maxLightnings;
this.stormParams.lightningMinPeriod = source.stormParams.lightningMinPeriod;
this.stormParams.lightningMaxPeriod = source.stormParams.lightningMaxPeriod;
this.stormParams.lightningMinDuration = source.stormParams.lightningMinDuration;
this.stormParams.lightningMaxDuration = source.stormParams.lightningMaxDuration;
this.lightningParameters = THREE.LightningStrike.copyParameters( {}, source.lightningParameters );
this.lightningMaterial = source.stormParams.lightningMaterial;
this.onLightningDown = source.onLightningDown;
return this;
};
THREE.LightningStrike.prototype.clone = function () {
return new this.constructor( this.stormParams ).copy( this );
};

1271
node_modules/three/examples/js/objects/MarchingCubes.js generated vendored Normal file

File diff suppressed because it is too large Load diff

240
node_modules/three/examples/js/objects/Reflector.js generated vendored Normal file
View file

@ -0,0 +1,240 @@
THREE.Reflector = function ( geometry, options ) {
THREE.Mesh.call( this, geometry );
this.type = 'Reflector';
var scope = this;
options = options || {};
var color = ( options.color !== undefined ) ? new THREE.Color( options.color ) : new THREE.Color( 0x7F7F7F );
var textureWidth = options.textureWidth || 512;
var textureHeight = options.textureHeight || 512;
var clipBias = options.clipBias || 0;
var shader = options.shader || THREE.Reflector.ReflectorShader;
//
var reflectorPlane = new THREE.Plane();
var normal = new THREE.Vector3();
var reflectorWorldPosition = new THREE.Vector3();
var cameraWorldPosition = new THREE.Vector3();
var rotationMatrix = new THREE.Matrix4();
var lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
var clipPlane = new THREE.Vector4();
var view = new THREE.Vector3();
var target = new THREE.Vector3();
var q = new THREE.Vector4();
var textureMatrix = new THREE.Matrix4();
var virtualCamera = new THREE.PerspectiveCamera();
var parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat
};
var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters );
if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) {
renderTarget.texture.generateMipmaps = false;
}
var material = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader
} );
material.uniforms[ 'tDiffuse' ].value = renderTarget.texture;
material.uniforms[ 'color' ].value = color;
material.uniforms[ 'textureMatrix' ].value = textureMatrix;
this.material = material;
this.onBeforeRender = function ( renderer, scene, camera ) {
reflectorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
cameraWorldPosition.setFromMatrixPosition( camera.matrixWorld );
rotationMatrix.extractRotation( scope.matrixWorld );
normal.set( 0, 0, 1 );
normal.applyMatrix4( rotationMatrix );
view.subVectors( reflectorWorldPosition, cameraWorldPosition );
// Avoid rendering when reflector is facing away
if ( view.dot( normal ) > 0 ) return;
view.reflect( normal ).negate();
view.add( reflectorWorldPosition );
rotationMatrix.extractRotation( camera.matrixWorld );
lookAtPosition.set( 0, 0, - 1 );
lookAtPosition.applyMatrix4( rotationMatrix );
lookAtPosition.add( cameraWorldPosition );
target.subVectors( reflectorWorldPosition, lookAtPosition );
target.reflect( normal ).negate();
target.add( reflectorWorldPosition );
virtualCamera.position.copy( view );
virtualCamera.up.set( 0, 1, 0 );
virtualCamera.up.applyMatrix4( rotationMatrix );
virtualCamera.up.reflect( normal );
virtualCamera.lookAt( target );
virtualCamera.far = camera.far; // Used in WebGLBackground
virtualCamera.updateMatrixWorld();
virtualCamera.projectionMatrix.copy( camera.projectionMatrix );
// Update the texture matrix
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
);
textureMatrix.multiply( virtualCamera.projectionMatrix );
textureMatrix.multiply( virtualCamera.matrixWorldInverse );
textureMatrix.multiply( scope.matrixWorld );
// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
reflectorPlane.setFromNormalAndCoplanarPoint( normal, reflectorWorldPosition );
reflectorPlane.applyMatrix4( virtualCamera.matrixWorldInverse );
clipPlane.set( reflectorPlane.normal.x, reflectorPlane.normal.y, reflectorPlane.normal.z, reflectorPlane.constant );
var projectionMatrix = virtualCamera.projectionMatrix;
q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
q.y = ( Math.sign( clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
q.z = - 1.0;
q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
// Calculate the scaled plane vector
clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) );
// Replacing the third row of the projection matrix
projectionMatrix.elements[ 2 ] = clipPlane.x;
projectionMatrix.elements[ 6 ] = clipPlane.y;
projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias;
projectionMatrix.elements[ 14 ] = clipPlane.w;
// Render
renderTarget.texture.encoding = renderer.outputEncoding;
scope.visible = false;
var currentRenderTarget = renderer.getRenderTarget();
var currentXrEnabled = renderer.xr.enabled;
var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
renderer.xr.enabled = false; // Avoid camera modification
renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
renderer.setRenderTarget( renderTarget );
renderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897
if ( renderer.autoClear === false ) renderer.clear();
renderer.render( scene, virtualCamera );
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.setRenderTarget( currentRenderTarget );
// Restore viewport
var viewport = camera.viewport;
if ( viewport !== undefined ) {
renderer.state.viewport( viewport );
}
scope.visible = true;
};
this.getRenderTarget = function () {
return renderTarget;
};
};
THREE.Reflector.prototype = Object.create( THREE.Mesh.prototype );
THREE.Reflector.prototype.constructor = THREE.Reflector;
THREE.Reflector.ReflectorShader = {
uniforms: {
'color': {
value: null
},
'tDiffuse': {
value: null
},
'textureMatrix': {
value: null
}
},
vertexShader: [
'uniform mat4 textureMatrix;',
'varying vec4 vUv;',
'void main() {',
' vUv = textureMatrix * vec4( position, 1.0 );',
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
'}'
].join( '\n' ),
fragmentShader: [
'uniform vec3 color;',
'uniform sampler2D tDiffuse;',
'varying vec4 vUv;',
'float blendOverlay( float base, float blend ) {',
' return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );',
'}',
'vec3 blendOverlay( vec3 base, vec3 blend ) {',
' return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );',
'}',
'void main() {',
' vec4 base = texture2DProj( tDiffuse, vUv );',
' gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );',
'}'
].join( '\n' )
};

View file

@ -0,0 +1,9 @@
THREE.ReflectorRTT = function ( geometry, options ) {
THREE.Reflector.call( this, geometry, options );
this.geometry.setDrawRange( 0, 0 ); // avoid rendering geometry
};
THREE.ReflectorRTT.prototype = Object.create( THREE.Reflector.prototype );

315
node_modules/three/examples/js/objects/Refractor.js generated vendored Normal file
View file

@ -0,0 +1,315 @@
THREE.Refractor = function ( geometry, options ) {
THREE.Mesh.call( this, geometry );
this.type = 'Refractor';
var scope = this;
options = options || {};
var color = ( options.color !== undefined ) ? new THREE.Color( options.color ) : new THREE.Color( 0x7F7F7F );
var textureWidth = options.textureWidth || 512;
var textureHeight = options.textureHeight || 512;
var clipBias = options.clipBias || 0;
var shader = options.shader || THREE.Refractor.RefractorShader;
//
var virtualCamera = new THREE.PerspectiveCamera();
virtualCamera.matrixAutoUpdate = false;
virtualCamera.userData.refractor = true;
//
var refractorPlane = new THREE.Plane();
var textureMatrix = new THREE.Matrix4();
// render target
var parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat
};
var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters );
if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) {
renderTarget.texture.generateMipmaps = false;
}
// material
this.material = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true // ensures, refractors are drawn from farthest to closest
} );
this.material.uniforms[ 'color' ].value = color;
this.material.uniforms[ 'tDiffuse' ].value = renderTarget.texture;
this.material.uniforms[ 'textureMatrix' ].value = textureMatrix;
// functions
var visible = ( function () {
var refractorWorldPosition = new THREE.Vector3();
var cameraWorldPosition = new THREE.Vector3();
var rotationMatrix = new THREE.Matrix4();
var view = new THREE.Vector3();
var normal = new THREE.Vector3();
return function visible( camera ) {
refractorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
cameraWorldPosition.setFromMatrixPosition( camera.matrixWorld );
view.subVectors( refractorWorldPosition, cameraWorldPosition );
rotationMatrix.extractRotation( scope.matrixWorld );
normal.set( 0, 0, 1 );
normal.applyMatrix4( rotationMatrix );
return view.dot( normal ) < 0;
};
} )();
var updateRefractorPlane = ( function () {
var normal = new THREE.Vector3();
var position = new THREE.Vector3();
var quaternion = new THREE.Quaternion();
var scale = new THREE.Vector3();
return function updateRefractorPlane() {
scope.matrixWorld.decompose( position, quaternion, scale );
normal.set( 0, 0, 1 ).applyQuaternion( quaternion ).normalize();
// flip the normal because we want to cull everything above the plane
normal.negate();
refractorPlane.setFromNormalAndCoplanarPoint( normal, position );
};
} )();
var updateVirtualCamera = ( function () {
var clipPlane = new THREE.Plane();
var clipVector = new THREE.Vector4();
var q = new THREE.Vector4();
return function updateVirtualCamera( camera ) {
virtualCamera.matrixWorld.copy( camera.matrixWorld );
virtualCamera.matrixWorldInverse.copy( virtualCamera.matrixWorld ).invert();
virtualCamera.projectionMatrix.copy( camera.projectionMatrix );
virtualCamera.far = camera.far; // used in WebGLBackground
// The following code creates an oblique view frustum for clipping.
// see: Lengyel, Eric. “Oblique View Frustum Depth Projection and Clipping”.
// Journal of Game Development, Vol. 1, No. 2 (2005), Charles River Media, pp. 516
clipPlane.copy( refractorPlane );
clipPlane.applyMatrix4( virtualCamera.matrixWorldInverse );
clipVector.set( clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant );
// calculate the clip-space corner point opposite the clipping plane and
// transform it into camera space by multiplying it by the inverse of the projection matrix
var projectionMatrix = virtualCamera.projectionMatrix;
q.x = ( Math.sign( clipVector.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
q.y = ( Math.sign( clipVector.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
q.z = - 1.0;
q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
// calculate the scaled plane vector
clipVector.multiplyScalar( 2.0 / clipVector.dot( q ) );
// replacing the third row of the projection matrix
projectionMatrix.elements[ 2 ] = clipVector.x;
projectionMatrix.elements[ 6 ] = clipVector.y;
projectionMatrix.elements[ 10 ] = clipVector.z + 1.0 - clipBias;
projectionMatrix.elements[ 14 ] = clipVector.w;
};
} )();
// This will update the texture matrix that is used for projective texture mapping in the shader.
// see: http://developer.download.nvidia.com/assets/gamedev/docs/projective_texture_mapping.pdf
function updateTextureMatrix( camera ) {
// this matrix does range mapping to [ 0, 1 ]
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
);
// we use "Object Linear Texgen", so we need to multiply the texture matrix T
// (matrix above) with the projection and view matrix of the virtual camera
// and the model matrix of the refractor
textureMatrix.multiply( camera.projectionMatrix );
textureMatrix.multiply( camera.matrixWorldInverse );
textureMatrix.multiply( scope.matrixWorld );
}
//
function render( renderer, scene, camera ) {
scope.visible = false;
var currentRenderTarget = renderer.getRenderTarget();
var currentXrEnabled = renderer.xr.enabled;
var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
renderer.xr.enabled = false; // avoid camera modification
renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows
renderer.setRenderTarget( renderTarget );
if ( renderer.autoClear === false ) renderer.clear();
renderer.render( scene, virtualCamera );
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.setRenderTarget( currentRenderTarget );
// restore viewport
var viewport = camera.viewport;
if ( viewport !== undefined ) {
renderer.state.viewport( viewport );
}
scope.visible = true;
}
//
this.onBeforeRender = function ( renderer, scene, camera ) {
// Render
renderTarget.texture.encoding = renderer.outputEncoding;
// ensure refractors are rendered only once per frame
if ( camera.userData.refractor === true ) return;
// avoid rendering when the refractor is viewed from behind
if ( ! visible( camera ) === true ) return;
// update
updateRefractorPlane();
updateTextureMatrix( camera );
updateVirtualCamera( camera );
render( renderer, scene, camera );
};
this.getRenderTarget = function () {
return renderTarget;
};
};
THREE.Refractor.prototype = Object.create( THREE.Mesh.prototype );
THREE.Refractor.prototype.constructor = THREE.Refractor;
THREE.Refractor.RefractorShader = {
uniforms: {
'color': {
value: null
},
'tDiffuse': {
value: null
},
'textureMatrix': {
value: null
}
},
vertexShader: [
'uniform mat4 textureMatrix;',
'varying vec4 vUv;',
'void main() {',
' vUv = textureMatrix * vec4( position, 1.0 );',
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
'}'
].join( '\n' ),
fragmentShader: [
'uniform vec3 color;',
'uniform sampler2D tDiffuse;',
'varying vec4 vUv;',
'float blendOverlay( float base, float blend ) {',
' return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );',
'}',
'vec3 blendOverlay( vec3 base, vec3 blend ) {',
' return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );',
'}',
'void main() {',
' vec4 base = texture2DProj( tDiffuse, vUv );',
' gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );',
'}'
].join( '\n' )
};

67
node_modules/three/examples/js/objects/ShadowMesh.js generated vendored Normal file
View file

@ -0,0 +1,67 @@
/**
* A shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane.
*/
THREE.ShadowMesh = function ( mesh ) {
var shadowMaterial = new THREE.MeshBasicMaterial( {
color: 0x000000,
transparent: true,
opacity: 0.6,
depthWrite: false
} );
THREE.Mesh.call( this, mesh.geometry, shadowMaterial );
this.meshMatrix = mesh.matrixWorld;
this.frustumCulled = false;
this.matrixAutoUpdate = false;
};
THREE.ShadowMesh.prototype = Object.create( THREE.Mesh.prototype );
THREE.ShadowMesh.prototype.constructor = THREE.ShadowMesh;
THREE.ShadowMesh.prototype.update = function () {
var shadowMatrix = new THREE.Matrix4();
return function ( plane, lightPosition4D ) {
// based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm
var dot = plane.normal.x * lightPosition4D.x +
plane.normal.y * lightPosition4D.y +
plane.normal.z * lightPosition4D.z +
- plane.constant * lightPosition4D.w;
var sme = shadowMatrix.elements;
sme[ 0 ] = dot - lightPosition4D.x * plane.normal.x;
sme[ 4 ] = - lightPosition4D.x * plane.normal.y;
sme[ 8 ] = - lightPosition4D.x * plane.normal.z;
sme[ 12 ] = - lightPosition4D.x * - plane.constant;
sme[ 1 ] = - lightPosition4D.y * plane.normal.x;
sme[ 5 ] = dot - lightPosition4D.y * plane.normal.y;
sme[ 9 ] = - lightPosition4D.y * plane.normal.z;
sme[ 13 ] = - lightPosition4D.y * - plane.constant;
sme[ 2 ] = - lightPosition4D.z * plane.normal.x;
sme[ 6 ] = - lightPosition4D.z * plane.normal.y;
sme[ 10 ] = dot - lightPosition4D.z * plane.normal.z;
sme[ 14 ] = - lightPosition4D.z * - plane.constant;
sme[ 3 ] = - lightPosition4D.w * plane.normal.x;
sme[ 7 ] = - lightPosition4D.w * plane.normal.y;
sme[ 11 ] = - lightPosition4D.w * plane.normal.z;
sme[ 15 ] = dot - lightPosition4D.w * - plane.constant;
this.matrix.multiplyMatrices( shadowMatrix, this.meshMatrix );
};
}();

206
node_modules/three/examples/js/objects/Sky.js generated vendored Normal file
View file

@ -0,0 +1,206 @@
/**
* Based on "A Practical Analytic Model for Daylight"
* aka The Preetham Model, the de facto standard analytic skydome model
* https://www.researchgate.net/publication/220720443_A_Practical_Analytic_Model_for_Daylight
*
* First implemented by Simon Wallner
* http://www.simonwallner.at/projects/atmospheric-scattering
*
* Improved by Martin Upitis
* http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR
*
* Three.js integration by zz85 http://twitter.com/blurspline
*/
THREE.Sky = function () {
var shader = THREE.Sky.SkyShader;
var material = new THREE.ShaderMaterial( {
name: 'SkyShader',
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
side: THREE.BackSide,
depthWrite: false
} );
THREE.Mesh.call( this, new THREE.BoxGeometry( 1, 1, 1 ), material );
};
THREE.Sky.prototype = Object.create( THREE.Mesh.prototype );
THREE.Sky.SkyShader = {
uniforms: {
'turbidity': { value: 2 },
'rayleigh': { value: 1 },
'mieCoefficient': { value: 0.005 },
'mieDirectionalG': { value: 0.8 },
'sunPosition': { value: new THREE.Vector3() },
'up': { value: new THREE.Vector3( 0, 1, 0 ) }
},
vertexShader: [
'uniform vec3 sunPosition;',
'uniform float rayleigh;',
'uniform float turbidity;',
'uniform float mieCoefficient;',
'uniform vec3 up;',
'varying vec3 vWorldPosition;',
'varying vec3 vSunDirection;',
'varying float vSunfade;',
'varying vec3 vBetaR;',
'varying vec3 vBetaM;',
'varying float vSunE;',
// constants for atmospheric scattering
'const float e = 2.71828182845904523536028747135266249775724709369995957;',
'const float pi = 3.141592653589793238462643383279502884197169;',
// wavelength of used primaries, according to preetham
'const vec3 lambda = vec3( 680E-9, 550E-9, 450E-9 );',
// this pre-calcuation replaces older TotalRayleigh(vec3 lambda) function:
// (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn))
'const vec3 totalRayleigh = vec3( 5.804542996261093E-6, 1.3562911419845635E-5, 3.0265902468824876E-5 );',
// mie stuff
// K coefficient for the primaries
'const float v = 4.0;',
'const vec3 K = vec3( 0.686, 0.678, 0.666 );',
// MieConst = pi * pow( ( 2.0 * pi ) / lambda, vec3( v - 2.0 ) ) * K
'const vec3 MieConst = vec3( 1.8399918514433978E14, 2.7798023919660528E14, 4.0790479543861094E14 );',
// earth shadow hack
// cutoffAngle = pi / 1.95;
'const float cutoffAngle = 1.6110731556870734;',
'const float steepness = 1.5;',
'const float EE = 1000.0;',
'float sunIntensity( float zenithAngleCos ) {',
' zenithAngleCos = clamp( zenithAngleCos, -1.0, 1.0 );',
' return EE * max( 0.0, 1.0 - pow( e, -( ( cutoffAngle - acos( zenithAngleCos ) ) / steepness ) ) );',
'}',
'vec3 totalMie( float T ) {',
' float c = ( 0.2 * T ) * 10E-18;',
' return 0.434 * c * MieConst;',
'}',
'void main() {',
' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
' vWorldPosition = worldPosition.xyz;',
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
' gl_Position.z = gl_Position.w;', // set z to camera.far
' vSunDirection = normalize( sunPosition );',
' vSunE = sunIntensity( dot( vSunDirection, up ) );',
' vSunfade = 1.0 - clamp( 1.0 - exp( ( sunPosition.y / 450000.0 ) ), 0.0, 1.0 );',
' float rayleighCoefficient = rayleigh - ( 1.0 * ( 1.0 - vSunfade ) );',
// extinction (absorbtion + out scattering)
// rayleigh coefficients
' vBetaR = totalRayleigh * rayleighCoefficient;',
// mie coefficients
' vBetaM = totalMie( turbidity ) * mieCoefficient;',
'}'
].join( '\n' ),
fragmentShader: [
'varying vec3 vWorldPosition;',
'varying vec3 vSunDirection;',
'varying float vSunfade;',
'varying vec3 vBetaR;',
'varying vec3 vBetaM;',
'varying float vSunE;',
'uniform float mieDirectionalG;',
'uniform vec3 up;',
'const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );',
// constants for atmospheric scattering
'const float pi = 3.141592653589793238462643383279502884197169;',
'const float n = 1.0003;', // refractive index of air
'const float N = 2.545E25;', // number of molecules per unit volume for air at 288.15K and 1013mb (sea level -45 celsius)
// optical length at zenith for molecules
'const float rayleighZenithLength = 8.4E3;',
'const float mieZenithLength = 1.25E3;',
// 66 arc seconds -> degrees, and the cosine of that
'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;',
// 3.0 / ( 16.0 * pi )
'const float THREE_OVER_SIXTEENPI = 0.05968310365946075;',
// 1.0 / ( 4.0 * pi )
'const float ONE_OVER_FOURPI = 0.07957747154594767;',
'float rayleighPhase( float cosTheta ) {',
' return THREE_OVER_SIXTEENPI * ( 1.0 + pow( cosTheta, 2.0 ) );',
'}',
'float hgPhase( float cosTheta, float g ) {',
' float g2 = pow( g, 2.0 );',
' float inverse = 1.0 / pow( 1.0 - 2.0 * g * cosTheta + g2, 1.5 );',
' return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inverse );',
'}',
'void main() {',
' vec3 direction = normalize( vWorldPosition - cameraPos );',
// optical length
// cutoff angle at 90 to avoid singularity in next formula.
' float zenithAngle = acos( max( 0.0, dot( up, direction ) ) );',
' float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );',
' float sR = rayleighZenithLength * inverse;',
' float sM = mieZenithLength * inverse;',
// combined extinction factor
' vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );',
// in scattering
' float cosTheta = dot( direction, vSunDirection );',
' float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );',
' vec3 betaRTheta = vBetaR * rPhase;',
' float mPhase = hgPhase( cosTheta, mieDirectionalG );',
' vec3 betaMTheta = vBetaM * mPhase;',
' vec3 Lin = pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * ( 1.0 - Fex ), vec3( 1.5 ) );',
' Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );',
// nightsky
' float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]',
' float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]',
' vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );',
' vec3 L0 = vec3( 0.1 ) * Fex;',
// composition + solar disc
' float sundisk = smoothstep( sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta );',
' L0 += ( vSunE * 19000.0 * Fex ) * sundisk;',
' vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );',
' vec3 retColor = pow( texColor, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );',
' gl_FragColor = vec4( retColor, 1.0 );',
'#include <tonemapping_fragment>',
'#include <encodings_fragment>',
'}'
].join( '\n' )
};

343
node_modules/three/examples/js/objects/Water.js generated vendored Normal file
View file

@ -0,0 +1,343 @@
/**
* Work based on :
* http://slayvin.net : Flat mirror for three.js
* http://www.adelphi.edu/~stemkoski : An implementation of water shader based on the flat mirror
* http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL
*/
THREE.Water = function ( geometry, options ) {
THREE.Mesh.call( this, geometry );
var scope = this;
options = options || {};
var textureWidth = options.textureWidth !== undefined ? options.textureWidth : 512;
var textureHeight = options.textureHeight !== undefined ? options.textureHeight : 512;
var clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
var alpha = options.alpha !== undefined ? options.alpha : 1.0;
var time = options.time !== undefined ? options.time : 0.0;
var normalSampler = options.waterNormals !== undefined ? options.waterNormals : null;
var sunDirection = options.sunDirection !== undefined ? options.sunDirection : new THREE.Vector3( 0.70707, 0.70707, 0.0 );
var sunColor = new THREE.Color( options.sunColor !== undefined ? options.sunColor : 0xffffff );
var waterColor = new THREE.Color( options.waterColor !== undefined ? options.waterColor : 0x7F7F7F );
var eye = options.eye !== undefined ? options.eye : new THREE.Vector3( 0, 0, 0 );
var distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;
var side = options.side !== undefined ? options.side : THREE.FrontSide;
var fog = options.fog !== undefined ? options.fog : false;
//
var mirrorPlane = new THREE.Plane();
var normal = new THREE.Vector3();
var mirrorWorldPosition = new THREE.Vector3();
var cameraWorldPosition = new THREE.Vector3();
var rotationMatrix = new THREE.Matrix4();
var lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
var clipPlane = new THREE.Vector4();
var view = new THREE.Vector3();
var target = new THREE.Vector3();
var q = new THREE.Vector4();
var textureMatrix = new THREE.Matrix4();
var mirrorCamera = new THREE.PerspectiveCamera();
var parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat
};
var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters );
if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) {
renderTarget.texture.generateMipmaps = false;
}
var mirrorShader = {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ 'fog' ],
THREE.UniformsLib[ 'lights' ],
{
'normalSampler': { value: null },
'mirrorSampler': { value: null },
'alpha': { value: 1.0 },
'time': { value: 0.0 },
'size': { value: 1.0 },
'distortionScale': { value: 20.0 },
'textureMatrix': { value: new THREE.Matrix4() },
'sunColor': { value: new THREE.Color( 0x7F7F7F ) },
'sunDirection': { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
'eye': { value: new THREE.Vector3() },
'waterColor': { value: new THREE.Color( 0x555555 ) }
}
] ),
vertexShader: [
'uniform mat4 textureMatrix;',
'uniform float time;',
'varying vec4 mirrorCoord;',
'varying vec4 worldPosition;',
'#include <common>',
'#include <fog_pars_vertex>',
'#include <shadowmap_pars_vertex>',
'#include <logdepthbuf_pars_vertex>',
'void main() {',
' mirrorCoord = modelMatrix * vec4( position, 1.0 );',
' worldPosition = mirrorCoord.xyzw;',
' mirrorCoord = textureMatrix * mirrorCoord;',
' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
' gl_Position = projectionMatrix * mvPosition;',
'#include <beginnormal_vertex>',
'#include <defaultnormal_vertex>',
'#include <logdepthbuf_vertex>',
'#include <fog_vertex>',
'#include <shadowmap_vertex>',
'}'
].join( '\n' ),
fragmentShader: [
'uniform sampler2D mirrorSampler;',
'uniform float alpha;',
'uniform float time;',
'uniform float size;',
'uniform float distortionScale;',
'uniform sampler2D normalSampler;',
'uniform vec3 sunColor;',
'uniform vec3 sunDirection;',
'uniform vec3 eye;',
'uniform vec3 waterColor;',
'varying vec4 mirrorCoord;',
'varying vec4 worldPosition;',
'vec4 getNoise( vec2 uv ) {',
' vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);',
' vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );',
' vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );',
' vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );',
' vec4 noise = texture2D( normalSampler, uv0 ) +',
' texture2D( normalSampler, uv1 ) +',
' texture2D( normalSampler, uv2 ) +',
' texture2D( normalSampler, uv3 );',
' return noise * 0.5 - 1.0;',
'}',
'void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {',
' vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );',
' float direction = max( 0.0, dot( eyeDirection, reflection ) );',
' specularColor += pow( direction, shiny ) * sunColor * spec;',
' diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;',
'}',
'#include <common>',
'#include <packing>',
'#include <bsdfs>',
'#include <fog_pars_fragment>',
'#include <logdepthbuf_pars_fragment>',
'#include <lights_pars_begin>',
'#include <shadowmap_pars_fragment>',
'#include <shadowmask_pars_fragment>',
'void main() {',
'#include <logdepthbuf_fragment>',
' vec4 noise = getNoise( worldPosition.xz * size );',
' vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );',
' vec3 diffuseLight = vec3(0.0);',
' vec3 specularLight = vec3(0.0);',
' vec3 worldToEye = eye-worldPosition.xyz;',
' vec3 eyeDirection = normalize( worldToEye );',
' sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );',
' float distance = length(worldToEye);',
' vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;',
' vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );',
' float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );',
' float rf0 = 0.3;',
' float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );',
' vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;',
' vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);',
' vec3 outgoingLight = albedo;',
' gl_FragColor = vec4( outgoingLight, alpha );',
'#include <tonemapping_fragment>',
'#include <fog_fragment>',
'}'
].join( '\n' )
};
var material = new THREE.ShaderMaterial( {
fragmentShader: mirrorShader.fragmentShader,
vertexShader: mirrorShader.vertexShader,
uniforms: THREE.UniformsUtils.clone( mirrorShader.uniforms ),
lights: true,
side: side,
fog: fog
} );
material.uniforms[ 'mirrorSampler' ].value = renderTarget.texture;
material.uniforms[ 'textureMatrix' ].value = textureMatrix;
material.uniforms[ 'alpha' ].value = alpha;
material.uniforms[ 'time' ].value = time;
material.uniforms[ 'normalSampler' ].value = normalSampler;
material.uniforms[ 'sunColor' ].value = sunColor;
material.uniforms[ 'waterColor' ].value = waterColor;
material.uniforms[ 'sunDirection' ].value = sunDirection;
material.uniforms[ 'distortionScale' ].value = distortionScale;
material.uniforms[ 'eye' ].value = eye;
scope.material = material;
scope.onBeforeRender = function ( renderer, scene, camera ) {
mirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
cameraWorldPosition.setFromMatrixPosition( camera.matrixWorld );
rotationMatrix.extractRotation( scope.matrixWorld );
normal.set( 0, 0, 1 );
normal.applyMatrix4( rotationMatrix );
view.subVectors( mirrorWorldPosition, cameraWorldPosition );
// Avoid rendering when mirror is facing away
if ( view.dot( normal ) > 0 ) return;
view.reflect( normal ).negate();
view.add( mirrorWorldPosition );
rotationMatrix.extractRotation( camera.matrixWorld );
lookAtPosition.set( 0, 0, - 1 );
lookAtPosition.applyMatrix4( rotationMatrix );
lookAtPosition.add( cameraWorldPosition );
target.subVectors( mirrorWorldPosition, lookAtPosition );
target.reflect( normal ).negate();
target.add( mirrorWorldPosition );
mirrorCamera.position.copy( view );
mirrorCamera.up.set( 0, 1, 0 );
mirrorCamera.up.applyMatrix4( rotationMatrix );
mirrorCamera.up.reflect( normal );
mirrorCamera.lookAt( target );
mirrorCamera.far = camera.far; // Used in WebGLBackground
mirrorCamera.updateMatrixWorld();
mirrorCamera.projectionMatrix.copy( camera.projectionMatrix );
// Update the texture matrix
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
);
textureMatrix.multiply( mirrorCamera.projectionMatrix );
textureMatrix.multiply( mirrorCamera.matrixWorldInverse );
// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
mirrorPlane.setFromNormalAndCoplanarPoint( normal, mirrorWorldPosition );
mirrorPlane.applyMatrix4( mirrorCamera.matrixWorldInverse );
clipPlane.set( mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant );
var projectionMatrix = mirrorCamera.projectionMatrix;
q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
q.y = ( Math.sign( clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
q.z = - 1.0;
q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
// Calculate the scaled plane vector
clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) );
// Replacing the third row of the projection matrix
projectionMatrix.elements[ 2 ] = clipPlane.x;
projectionMatrix.elements[ 6 ] = clipPlane.y;
projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias;
projectionMatrix.elements[ 14 ] = clipPlane.w;
eye.setFromMatrixPosition( camera.matrixWorld );
// Render
if ( renderer.outputEncoding !== THREE.LinearEncoding ) {
console.warn( 'THREE.Water: WebGLRenderer must use LinearEncoding as outputEncoding.' );
scope.onBeforeRender = function () {};
return;
}
if ( renderer.toneMapping !== THREE.NoToneMapping ) {
console.warn( 'THREE.Water: WebGLRenderer must use NoToneMapping as toneMapping.' );
scope.onBeforeRender = function () {};
return;
}
var currentRenderTarget = renderer.getRenderTarget();
var currentXrEnabled = renderer.xr.enabled;
var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
scope.visible = false;
renderer.xr.enabled = false; // Avoid camera modification and recursion
renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
renderer.setRenderTarget( renderTarget );
renderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897
if ( renderer.autoClear === false ) renderer.clear();
renderer.render( scene, mirrorCamera );
scope.visible = true;
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.setRenderTarget( currentRenderTarget );
// Restore viewport
var viewport = camera.viewport;
if ( viewport !== undefined ) {
renderer.state.viewport( viewport );
}
};
};
THREE.Water.prototype = Object.create( THREE.Mesh.prototype );
THREE.Water.prototype.constructor = THREE.Water;

345
node_modules/three/examples/js/objects/Water2.js generated vendored Normal file
View file

@ -0,0 +1,345 @@
/**
* References:
* http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html
*
*/
THREE.Water = function ( geometry, options ) {
THREE.Mesh.call( this, geometry );
this.type = 'Water';
var scope = this;
options = options || {};
var color = ( options.color !== undefined ) ? new THREE.Color( options.color ) : new THREE.Color( 0xFFFFFF );
var textureWidth = options.textureWidth || 512;
var textureHeight = options.textureHeight || 512;
var clipBias = options.clipBias || 0;
var flowDirection = options.flowDirection || new THREE.Vector2( 1, 0 );
var flowSpeed = options.flowSpeed || 0.03;
var reflectivity = options.reflectivity || 0.02;
var scale = options.scale || 1;
var shader = options.shader || THREE.Water.WaterShader;
var encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding;
var textureLoader = new THREE.TextureLoader();
var flowMap = options.flowMap || undefined;
var normalMap0 = options.normalMap0 || textureLoader.load( 'textures/water/Water_1_M_Normal.jpg' );
var normalMap1 = options.normalMap1 || textureLoader.load( 'textures/water/Water_2_M_Normal.jpg' );
var cycle = 0.15; // a cycle of a flow map phase
var halfCycle = cycle * 0.5;
var textureMatrix = new THREE.Matrix4();
var clock = new THREE.Clock();
// internal components
if ( THREE.Reflector === undefined ) {
console.error( 'THREE.Water: Required component THREE.Reflector not found.' );
return;
}
if ( THREE.Refractor === undefined ) {
console.error( 'THREE.Water: Required component THREE.Refractor not found.' );
return;
}
var reflector = new THREE.Reflector( geometry, {
textureWidth: textureWidth,
textureHeight: textureHeight,
clipBias: clipBias,
encoding: encoding
} );
var refractor = new THREE.Refractor( geometry, {
textureWidth: textureWidth,
textureHeight: textureHeight,
clipBias: clipBias,
encoding: encoding
} );
reflector.matrixAutoUpdate = false;
refractor.matrixAutoUpdate = false;
// material
this.material = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ 'fog' ],
shader.uniforms
] ),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true,
fog: true
} );
if ( flowMap !== undefined ) {
this.material.defines.USE_FLOWMAP = '';
this.material.uniforms[ 'tFlowMap' ] = {
type: 't',
value: flowMap
};
} else {
this.material.uniforms[ 'flowDirection' ] = {
type: 'v2',
value: flowDirection
};
}
// maps
normalMap0.wrapS = normalMap0.wrapT = THREE.RepeatWrapping;
normalMap1.wrapS = normalMap1.wrapT = THREE.RepeatWrapping;
this.material.uniforms[ 'tReflectionMap' ].value = reflector.getRenderTarget().texture;
this.material.uniforms[ 'tRefractionMap' ].value = refractor.getRenderTarget().texture;
this.material.uniforms[ 'tNormalMap0' ].value = normalMap0;
this.material.uniforms[ 'tNormalMap1' ].value = normalMap1;
// water
this.material.uniforms[ 'color' ].value = color;
this.material.uniforms[ 'reflectivity' ].value = reflectivity;
this.material.uniforms[ 'textureMatrix' ].value = textureMatrix;
// inital values
this.material.uniforms[ 'config' ].value.x = 0; // flowMapOffset0
this.material.uniforms[ 'config' ].value.y = halfCycle; // flowMapOffset1
this.material.uniforms[ 'config' ].value.z = halfCycle; // halfCycle
this.material.uniforms[ 'config' ].value.w = scale; // scale
// functions
function updateTextureMatrix( camera ) {
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
);
textureMatrix.multiply( camera.projectionMatrix );
textureMatrix.multiply( camera.matrixWorldInverse );
textureMatrix.multiply( scope.matrixWorld );
}
function updateFlow() {
var delta = clock.getDelta();
var config = scope.material.uniforms[ 'config' ];
config.value.x += flowSpeed * delta; // flowMapOffset0
config.value.y = config.value.x + halfCycle; // flowMapOffset1
// Important: The distance between offsets should be always the value of "halfCycle".
// Moreover, both offsets should be in the range of [ 0, cycle ].
// This approach ensures a smooth water flow and avoids "reset" effects.
if ( config.value.x >= cycle ) {
config.value.x = 0;
config.value.y = halfCycle;
} else if ( config.value.y >= cycle ) {
config.value.y = config.value.y - cycle;
}
}
//
this.onBeforeRender = function ( renderer, scene, camera ) {
updateTextureMatrix( camera );
updateFlow();
scope.visible = false;
reflector.matrixWorld.copy( scope.matrixWorld );
refractor.matrixWorld.copy( scope.matrixWorld );
reflector.onBeforeRender( renderer, scene, camera );
refractor.onBeforeRender( renderer, scene, camera );
scope.visible = true;
};
};
THREE.Water.prototype = Object.create( THREE.Mesh.prototype );
THREE.Water.prototype.constructor = THREE.Water;
THREE.Water.WaterShader = {
uniforms: {
'color': {
type: 'c',
value: null
},
'reflectivity': {
type: 'f',
value: 0
},
'tReflectionMap': {
type: 't',
value: null
},
'tRefractionMap': {
type: 't',
value: null
},
'tNormalMap0': {
type: 't',
value: null
},
'tNormalMap1': {
type: 't',
value: null
},
'textureMatrix': {
type: 'm4',
value: null
},
'config': {
type: 'v4',
value: new THREE.Vector4()
}
},
vertexShader: [
'#include <common>',
'#include <fog_pars_vertex>',
'#include <logdepthbuf_pars_vertex>',
'uniform mat4 textureMatrix;',
'varying vec4 vCoord;',
'varying vec2 vUv;',
'varying vec3 vToEye;',
'void main() {',
' vUv = uv;',
' vCoord = textureMatrix * vec4( position, 1.0 );',
' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
' vToEye = cameraPosition - worldPosition.xyz;',
' vec4 mvPosition = viewMatrix * worldPosition;', // used in fog_vertex
' gl_Position = projectionMatrix * mvPosition;',
' #include <logdepthbuf_vertex>',
' #include <fog_vertex>',
'}'
].join( '\n' ),
fragmentShader: [
'#include <common>',
'#include <fog_pars_fragment>',
'#include <logdepthbuf_pars_fragment>',
'uniform sampler2D tReflectionMap;',
'uniform sampler2D tRefractionMap;',
'uniform sampler2D tNormalMap0;',
'uniform sampler2D tNormalMap1;',
'#ifdef USE_FLOWMAP',
' uniform sampler2D tFlowMap;',
'#else',
' uniform vec2 flowDirection;',
'#endif',
'uniform vec3 color;',
'uniform float reflectivity;',
'uniform vec4 config;',
'varying vec4 vCoord;',
'varying vec2 vUv;',
'varying vec3 vToEye;',
'void main() {',
' #include <logdepthbuf_fragment>',
' float flowMapOffset0 = config.x;',
' float flowMapOffset1 = config.y;',
' float halfCycle = config.z;',
' float scale = config.w;',
' vec3 toEye = normalize( vToEye );',
// determine flow direction
' vec2 flow;',
' #ifdef USE_FLOWMAP',
' flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;',
' #else',
' flow = flowDirection;',
' #endif',
' flow.x *= - 1.0;',
// sample normal maps (distort uvs with flowdata)
' vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );',
' vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );',
// linear interpolate to get the final normal color
' float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;',
' vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );',
// calculate normal vector
' vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) );',
// calculate the fresnel term to blend reflection and refraction maps
' float theta = max( dot( toEye, normal ), 0.0 );',
' float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );',
// calculate final uv coords
' vec3 coord = vCoord.xyz / vCoord.w;',
' vec2 uv = coord.xy + coord.z * normal.xz * 0.05;',
' vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );',
' vec4 refractColor = texture2D( tRefractionMap, uv );',
// multiply water color with the mix of both textures
' gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );',
' #include <tonemapping_fragment>',
' #include <encodings_fragment>',
' #include <fog_fragment>',
'}'
].join( '\n' )
};