mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-05 19:42:38 +02:00
This commit is contained in:
parent
f0f62670c5
commit
7e26256cac
4563 changed files with 1246712 additions and 17558 deletions
25
node_modules/three/examples/jsm/objects/Lensflare.d.ts
generated
vendored
Normal file
25
node_modules/three/examples/jsm/objects/Lensflare.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
import {
|
||||
Mesh,
|
||||
Texture,
|
||||
Color
|
||||
} from '../../../src/Three';
|
||||
|
||||
export class LensflareElement {
|
||||
|
||||
constructor( texture: Texture, size?: number, distance?: number, color?: Color );
|
||||
texture: Texture;
|
||||
size: number;
|
||||
distance: number;
|
||||
color: Color;
|
||||
|
||||
}
|
||||
|
||||
export class Lensflare extends Mesh {
|
||||
|
||||
constructor();
|
||||
readonly isLensflare: true;
|
||||
|
||||
addElement( element: LensflareElement ): void;
|
||||
dispose(): void;
|
||||
|
||||
}
|
393
node_modules/three/examples/jsm/objects/Lensflare.js
generated
vendored
Normal file
393
node_modules/three/examples/jsm/objects/Lensflare.js
generated
vendored
Normal file
|
@ -0,0 +1,393 @@
|
|||
import {
|
||||
AdditiveBlending,
|
||||
Box2,
|
||||
BufferGeometry,
|
||||
ClampToEdgeWrapping,
|
||||
Color,
|
||||
DataTexture,
|
||||
InterleavedBuffer,
|
||||
InterleavedBufferAttribute,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
NearestFilter,
|
||||
RGBFormat,
|
||||
RawShaderMaterial,
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
var Lensflare = function () {
|
||||
|
||||
Mesh.call( this, Lensflare.Geometry, new MeshBasicMaterial( { opacity: 0, transparent: true } ) );
|
||||
|
||||
this.type = 'Lensflare';
|
||||
this.frustumCulled = false;
|
||||
this.renderOrder = Infinity;
|
||||
|
||||
//
|
||||
|
||||
var positionScreen = new Vector3();
|
||||
var positionView = new Vector3();
|
||||
|
||||
// textures
|
||||
|
||||
var tempMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat );
|
||||
tempMap.minFilter = NearestFilter;
|
||||
tempMap.magFilter = NearestFilter;
|
||||
tempMap.wrapS = ClampToEdgeWrapping;
|
||||
tempMap.wrapT = ClampToEdgeWrapping;
|
||||
|
||||
var occlusionMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat );
|
||||
occlusionMap.minFilter = NearestFilter;
|
||||
occlusionMap.magFilter = NearestFilter;
|
||||
occlusionMap.wrapS = ClampToEdgeWrapping;
|
||||
occlusionMap.wrapT = ClampToEdgeWrapping;
|
||||
|
||||
// material
|
||||
|
||||
var geometry = Lensflare.Geometry;
|
||||
|
||||
var material1a = new 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 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 Mesh( geometry, material1a );
|
||||
|
||||
//
|
||||
|
||||
var elements = [];
|
||||
|
||||
var shader = LensflareElement.Shader;
|
||||
|
||||
var material2 = new RawShaderMaterial( {
|
||||
uniforms: {
|
||||
'map': { value: null },
|
||||
'occlusionMap': { value: occlusionMap },
|
||||
'color': { value: new Color( 0xffffff ) },
|
||||
'scale': { value: new Vector2() },
|
||||
'screenPosition': { value: new Vector3() }
|
||||
},
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader,
|
||||
blending: AdditiveBlending,
|
||||
transparent: true,
|
||||
depthWrite: false
|
||||
} );
|
||||
|
||||
var mesh2 = new Mesh( geometry, material2 );
|
||||
|
||||
this.addElement = function ( element ) {
|
||||
|
||||
elements.push( element );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
var scale = new Vector2();
|
||||
var screenPositionPixels = new Vector2();
|
||||
var validArea = new Box2();
|
||||
var viewport = new 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();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Lensflare.prototype = Object.create( Mesh.prototype );
|
||||
Lensflare.prototype.constructor = Lensflare;
|
||||
Lensflare.prototype.isLensflare = true;
|
||||
|
||||
//
|
||||
|
||||
var LensflareElement = function ( texture, size, distance, color ) {
|
||||
|
||||
this.texture = texture;
|
||||
this.size = size || 1;
|
||||
this.distance = distance || 0;
|
||||
this.color = color || new Color( 0xffffff );
|
||||
|
||||
};
|
||||
|
||||
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' )
|
||||
|
||||
};
|
||||
|
||||
Lensflare.Geometry = ( function () {
|
||||
|
||||
var geometry = new 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 InterleavedBuffer( float32Array, 5 );
|
||||
|
||||
geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
|
||||
geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
|
||||
geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
|
||||
|
||||
return geometry;
|
||||
|
||||
} )();
|
||||
|
||||
export { Lensflare, LensflareElement };
|
37
node_modules/three/examples/jsm/objects/LightningStorm.d.ts
generated
vendored
Normal file
37
node_modules/three/examples/jsm/objects/LightningStorm.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
import {
|
||||
Material,
|
||||
Vector3
|
||||
} from '../../../src/Three';
|
||||
|
||||
import { LightningStrike, RayParameters } from '../geometries/LightningStrike';
|
||||
|
||||
export interface StormParams {
|
||||
size?: number;
|
||||
minHeight?: number;
|
||||
maxHeight?: number;
|
||||
maxSlope?: number;
|
||||
|
||||
maxLightnings?: number;
|
||||
|
||||
lightningMinPeriod?: number;
|
||||
lightningMaxPeriod?: number;
|
||||
lightningMinDuration?: number;
|
||||
lightningMaxDuration?: number;
|
||||
|
||||
lightningParameters?: RayParameters;
|
||||
lightningMaterial?: Material;
|
||||
|
||||
isEternal?: boolean;
|
||||
|
||||
onRayPosition?: ( source: Vector3, dest: Vector3 ) => void;
|
||||
onLightningDown?: ( lightning: LightningStrike ) => void;
|
||||
}
|
||||
|
||||
export class LightningStorm {
|
||||
|
||||
constructor( stormParams?: StormParams );
|
||||
update( time: number ): void;
|
||||
copy( source: LightningStorm ): LightningStorm;
|
||||
clone(): LightningStorm;
|
||||
|
||||
}
|
246
node_modules/three/examples/jsm/objects/LightningStorm.js
generated
vendored
Normal file
246
node_modules/three/examples/jsm/objects/LightningStorm.js
generated
vendored
Normal file
|
@ -0,0 +1,246 @@
|
|||
import {
|
||||
MathUtils,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
Object3D
|
||||
} from '../../../build/three.module.js';
|
||||
import { LightningStrike } from '../geometries/LightningStrike.js';
|
||||
|
||||
/**
|
||||
* @fileoverview Lightning strike object generator
|
||||
*
|
||||
*
|
||||
* Usage
|
||||
*
|
||||
* var myStorm = new 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 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
var LightningStorm = function ( stormParams ) {
|
||||
|
||||
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 = LightningStrike.copyParameters( stormParams.lightningParameters, stormParams.lightningParameters );
|
||||
|
||||
this.lightningParameters.isEternal = false;
|
||||
|
||||
this.lightningMaterial = stormParams.lightningMaterial !== undefined ? stormParams.lightningMaterial : new 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 = 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 LightningStrike( LightningStrike.copyParameters( {}, this.lightningParameters ) );
|
||||
var mesh = new Mesh( lightning, this.lightningMaterial );
|
||||
this.deadLightningsMeshes.push( mesh );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LightningStorm.prototype = Object.create( Object3D.prototype );
|
||||
|
||||
LightningStorm.prototype.constructor = LightningStorm;
|
||||
|
||||
LightningStorm.prototype.isLightningStorm = true;
|
||||
|
||||
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 = LightningStrike.copyParameters( lightningMesh.geometry.rayParameters, this.lightningParameters );
|
||||
|
||||
lightningParams1.birthTime = time;
|
||||
lightningParams1.deathTime = time + 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 === LightningStrike.RAY_PROPAGATING && lightning.state > prevState ) {
|
||||
|
||||
if ( this.onLightningDown ) {
|
||||
|
||||
this.onLightningDown( lightning );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( lightning.state === 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 ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LightningStorm.prototype.getNextLightningTime = function ( currentTime ) {
|
||||
|
||||
return currentTime + MathUtils.lerp( this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random() ) / ( this.stormParams.maxLightnings + 1 );
|
||||
|
||||
};
|
||||
|
||||
LightningStorm.prototype.copy = function ( source ) {
|
||||
|
||||
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 = LightningStrike.copyParameters( {}, source.lightningParameters );
|
||||
|
||||
this.lightningMaterial = source.stormParams.lightningMaterial;
|
||||
|
||||
this.onLightningDown = source.onLightningDown;
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
LightningStrike.prototype.clone = function () {
|
||||
|
||||
return new this.constructor( this.stormParams ).copy( this );
|
||||
|
||||
};
|
||||
|
||||
export { LightningStorm };
|
74
node_modules/three/examples/jsm/objects/MarchingCubes.d.ts
generated
vendored
Normal file
74
node_modules/three/examples/jsm/objects/MarchingCubes.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
import {
|
||||
BufferGeometry,
|
||||
Material,
|
||||
ImmediateRenderObject
|
||||
} from '../../../src/Three';
|
||||
|
||||
export class MarchingCubes extends ImmediateRenderObject {
|
||||
|
||||
constructor( resolution: number, material: Material, enableUvs?: boolean, enableColors?: boolean );
|
||||
|
||||
enableUvs: boolean;
|
||||
enableColors: boolean;
|
||||
|
||||
resolution: number;
|
||||
|
||||
// parameters
|
||||
|
||||
isolation: number;
|
||||
|
||||
// size of field, 32 is pushing it in Javascript :)
|
||||
|
||||
size: number;
|
||||
size2: number;
|
||||
size3: number;
|
||||
halfsize: number;
|
||||
|
||||
// deltas
|
||||
|
||||
delta: number;
|
||||
yd: number;
|
||||
zd: number;
|
||||
|
||||
field: Float32Array;
|
||||
normal_cache: Float32Array;
|
||||
palette: Float32Array;
|
||||
|
||||
maxCount: number;
|
||||
count: number;
|
||||
|
||||
hasPositions: boolean;
|
||||
hasNormals: boolean;
|
||||
hasColors: boolean;
|
||||
hasUvs: boolean;
|
||||
|
||||
positionArray: Float32Array;
|
||||
normalArray: Float32Array;
|
||||
|
||||
uvArray: Float32Array;
|
||||
colorArray: Float32Array;
|
||||
|
||||
begin(): void;
|
||||
end(): void;
|
||||
|
||||
addBall( ballx: number, bally: number, ballz: number, strength: number, subtract: number, colors: any ): void;
|
||||
|
||||
addPlaneX( strength: number, subtract: number ): void;
|
||||
addPlaneY( strength: number, subtract: number ): void;
|
||||
addPlaneZ( strength: number, subtract: number ): void;
|
||||
|
||||
setCell ( x: number, y: number, z: number, value: number ): void;
|
||||
getCell ( x: number, y: number, z: number ): number;
|
||||
|
||||
blur( intensity: number ): void;
|
||||
|
||||
reset(): void;
|
||||
render( renderCallback: any ): void;
|
||||
generateGeometry(): BufferGeometry;
|
||||
generateBufferGeometry(): BufferGeometry;
|
||||
|
||||
}
|
||||
|
||||
export const edgeTable: Int32Array[];
|
||||
export const triTable: Int32Array[];
|
||||
|
1281
node_modules/three/examples/jsm/objects/MarchingCubes.js
generated
vendored
Normal file
1281
node_modules/three/examples/jsm/objects/MarchingCubes.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
node_modules/three/examples/jsm/objects/Reflector.d.ts
generated
vendored
Normal file
24
node_modules/three/examples/jsm/objects/Reflector.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {
|
||||
Mesh,
|
||||
BufferGeometry,
|
||||
Color,
|
||||
TextureEncoding,
|
||||
WebGLRenderTarget
|
||||
} from '../../../src/Three';
|
||||
|
||||
export interface ReflectorOptions {
|
||||
color?: Color;
|
||||
textureWidth?: number;
|
||||
textureHeight?: number;
|
||||
clipBias?: number;
|
||||
shader?: object;
|
||||
encoding?: TextureEncoding;
|
||||
}
|
||||
|
||||
export class Reflector extends Mesh {
|
||||
|
||||
constructor( geometry?: BufferGeometry, options?: ReflectorOptions );
|
||||
|
||||
getRenderTarget(): WebGLRenderTarget;
|
||||
|
||||
}
|
258
node_modules/three/examples/jsm/objects/Reflector.js
generated
vendored
Normal file
258
node_modules/three/examples/jsm/objects/Reflector.js
generated
vendored
Normal file
|
@ -0,0 +1,258 @@
|
|||
import {
|
||||
Color,
|
||||
LinearFilter,
|
||||
MathUtils,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
PerspectiveCamera,
|
||||
Plane,
|
||||
RGBFormat,
|
||||
ShaderMaterial,
|
||||
UniformsUtils,
|
||||
Vector3,
|
||||
Vector4,
|
||||
WebGLRenderTarget
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
var Reflector = function ( geometry, options ) {
|
||||
|
||||
Mesh.call( this, geometry );
|
||||
|
||||
this.type = 'Reflector';
|
||||
|
||||
var scope = this;
|
||||
|
||||
options = options || {};
|
||||
|
||||
var color = ( options.color !== undefined ) ? new Color( options.color ) : new Color( 0x7F7F7F );
|
||||
var textureWidth = options.textureWidth || 512;
|
||||
var textureHeight = options.textureHeight || 512;
|
||||
var clipBias = options.clipBias || 0;
|
||||
var shader = options.shader || Reflector.ReflectorShader;
|
||||
|
||||
//
|
||||
|
||||
var reflectorPlane = new Plane();
|
||||
var normal = new Vector3();
|
||||
var reflectorWorldPosition = new Vector3();
|
||||
var cameraWorldPosition = new Vector3();
|
||||
var rotationMatrix = new Matrix4();
|
||||
var lookAtPosition = new Vector3( 0, 0, - 1 );
|
||||
var clipPlane = new Vector4();
|
||||
|
||||
var view = new Vector3();
|
||||
var target = new Vector3();
|
||||
var q = new Vector4();
|
||||
|
||||
var textureMatrix = new Matrix4();
|
||||
var virtualCamera = new PerspectiveCamera();
|
||||
|
||||
var parameters = {
|
||||
minFilter: LinearFilter,
|
||||
magFilter: LinearFilter,
|
||||
format: RGBFormat
|
||||
};
|
||||
|
||||
var renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
|
||||
|
||||
if ( ! MathUtils.isPowerOfTwo( textureWidth ) || ! MathUtils.isPowerOfTwo( textureHeight ) ) {
|
||||
|
||||
renderTarget.texture.generateMipmaps = false;
|
||||
|
||||
}
|
||||
|
||||
var material = new ShaderMaterial( {
|
||||
uniforms: 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;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Reflector.prototype = Object.create( Mesh.prototype );
|
||||
Reflector.prototype.constructor = Reflector;
|
||||
|
||||
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' )
|
||||
};
|
||||
|
||||
export { Reflector };
|
8
node_modules/three/examples/jsm/objects/ReflectorRTT.d.ts
generated
vendored
Normal file
8
node_modules/three/examples/jsm/objects/ReflectorRTT.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { BufferGeometry } from '../../../src/Three';
|
||||
import { Reflector, ReflectorOptions } from './Reflector';
|
||||
|
||||
export class ReflectorRTT extends Reflector {
|
||||
|
||||
constructor( geometry?: BufferGeometry, options?: ReflectorOptions );
|
||||
|
||||
}
|
13
node_modules/three/examples/jsm/objects/ReflectorRTT.js
generated
vendored
Normal file
13
node_modules/three/examples/jsm/objects/ReflectorRTT.js
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { Reflector } from '../objects/Reflector.js';
|
||||
|
||||
var ReflectorRTT = function ( geometry, options ) {
|
||||
|
||||
Reflector.call( this, geometry, options );
|
||||
|
||||
this.geometry.setDrawRange( 0, 0 ); // avoid rendering geometry
|
||||
|
||||
};
|
||||
|
||||
ReflectorRTT.prototype = Object.create( Reflector.prototype );
|
||||
|
||||
export { ReflectorRTT };
|
24
node_modules/three/examples/jsm/objects/Refractor.d.ts
generated
vendored
Normal file
24
node_modules/three/examples/jsm/objects/Refractor.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {
|
||||
Mesh,
|
||||
BufferGeometry,
|
||||
Color,
|
||||
TextureEncoding,
|
||||
WebGLRenderTarget
|
||||
} from '../../../src/Three';
|
||||
|
||||
export interface RefractorOptions {
|
||||
color?: Color;
|
||||
textureWidth?: number;
|
||||
textureHeight?: number;
|
||||
clipBias?: number;
|
||||
shader?: object;
|
||||
encoding?: TextureEncoding;
|
||||
}
|
||||
|
||||
export class Refractor extends Mesh {
|
||||
|
||||
constructor( geometry?: BufferGeometry, options?: RefractorOptions );
|
||||
|
||||
getRenderTarget(): WebGLRenderTarget;
|
||||
|
||||
}
|
334
node_modules/three/examples/jsm/objects/Refractor.js
generated
vendored
Normal file
334
node_modules/three/examples/jsm/objects/Refractor.js
generated
vendored
Normal file
|
@ -0,0 +1,334 @@
|
|||
import {
|
||||
Color,
|
||||
LinearFilter,
|
||||
MathUtils,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
PerspectiveCamera,
|
||||
Plane,
|
||||
Quaternion,
|
||||
RGBFormat,
|
||||
ShaderMaterial,
|
||||
UniformsUtils,
|
||||
Vector3,
|
||||
Vector4,
|
||||
WebGLRenderTarget
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
var Refractor = function ( geometry, options ) {
|
||||
|
||||
Mesh.call( this, geometry );
|
||||
|
||||
this.type = 'Refractor';
|
||||
|
||||
var scope = this;
|
||||
|
||||
options = options || {};
|
||||
|
||||
var color = ( options.color !== undefined ) ? new Color( options.color ) : new Color( 0x7F7F7F );
|
||||
var textureWidth = options.textureWidth || 512;
|
||||
var textureHeight = options.textureHeight || 512;
|
||||
var clipBias = options.clipBias || 0;
|
||||
var shader = options.shader || Refractor.RefractorShader;
|
||||
|
||||
//
|
||||
|
||||
var virtualCamera = new PerspectiveCamera();
|
||||
virtualCamera.matrixAutoUpdate = false;
|
||||
virtualCamera.userData.refractor = true;
|
||||
|
||||
//
|
||||
|
||||
var refractorPlane = new Plane();
|
||||
var textureMatrix = new Matrix4();
|
||||
|
||||
// render target
|
||||
|
||||
var parameters = {
|
||||
minFilter: LinearFilter,
|
||||
magFilter: LinearFilter,
|
||||
format: RGBFormat
|
||||
};
|
||||
|
||||
var renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
|
||||
|
||||
if ( ! MathUtils.isPowerOfTwo( textureWidth ) || ! MathUtils.isPowerOfTwo( textureHeight ) ) {
|
||||
|
||||
renderTarget.texture.generateMipmaps = false;
|
||||
|
||||
}
|
||||
|
||||
// material
|
||||
|
||||
this.material = new ShaderMaterial( {
|
||||
uniforms: 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 Vector3();
|
||||
var cameraWorldPosition = new Vector3();
|
||||
var rotationMatrix = new Matrix4();
|
||||
|
||||
var view = new Vector3();
|
||||
var normal = new 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 Vector3();
|
||||
var position = new Vector3();
|
||||
var quaternion = new Quaternion();
|
||||
var scale = new 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 Plane();
|
||||
var clipVector = new Vector4();
|
||||
var q = new 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. 5–16
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Refractor.prototype = Object.create( Mesh.prototype );
|
||||
Refractor.prototype.constructor = Refractor;
|
||||
|
||||
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' )
|
||||
};
|
||||
|
||||
export { Refractor };
|
13
node_modules/three/examples/jsm/objects/ShadowMesh.d.ts
generated
vendored
Normal file
13
node_modules/three/examples/jsm/objects/ShadowMesh.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import {
|
||||
Mesh,
|
||||
Plane,
|
||||
Vector4
|
||||
} from '../../../src/Three';
|
||||
|
||||
export class ShadowMesh extends Mesh {
|
||||
|
||||
constructor();
|
||||
|
||||
update( plane: Plane, lightPosition4D: Vector4 ): void;
|
||||
|
||||
}
|
75
node_modules/three/examples/jsm/objects/ShadowMesh.js
generated
vendored
Normal file
75
node_modules/three/examples/jsm/objects/ShadowMesh.js
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
import {
|
||||
Matrix4,
|
||||
Mesh,
|
||||
MeshBasicMaterial
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
/**
|
||||
* A shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane.
|
||||
*/
|
||||
|
||||
var ShadowMesh = function ( mesh ) {
|
||||
|
||||
var shadowMaterial = new MeshBasicMaterial( {
|
||||
|
||||
color: 0x000000,
|
||||
transparent: true,
|
||||
opacity: 0.6,
|
||||
depthWrite: false
|
||||
|
||||
} );
|
||||
|
||||
Mesh.call( this, mesh.geometry, shadowMaterial );
|
||||
|
||||
this.meshMatrix = mesh.matrixWorld;
|
||||
|
||||
this.frustumCulled = false;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
};
|
||||
|
||||
ShadowMesh.prototype = Object.create( Mesh.prototype );
|
||||
ShadowMesh.prototype.constructor = ShadowMesh;
|
||||
|
||||
ShadowMesh.prototype.update = function () {
|
||||
|
||||
var shadowMatrix = new 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 );
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
export { ShadowMesh };
|
16
node_modules/three/examples/jsm/objects/Sky.d.ts
generated
vendored
Normal file
16
node_modules/three/examples/jsm/objects/Sky.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
import {
|
||||
BoxGeometry,
|
||||
Mesh,
|
||||
ShaderMaterial
|
||||
} from '../../../src/Three';
|
||||
|
||||
export class Sky extends Mesh {
|
||||
|
||||
constructor();
|
||||
|
||||
geometry: BoxGeometry;
|
||||
material: ShaderMaterial;
|
||||
|
||||
static SkyShader: object;
|
||||
|
||||
}
|
217
node_modules/three/examples/jsm/objects/Sky.js
generated
vendored
Normal file
217
node_modules/three/examples/jsm/objects/Sky.js
generated
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
import {
|
||||
BackSide,
|
||||
BoxGeometry,
|
||||
Mesh,
|
||||
ShaderMaterial,
|
||||
UniformsUtils,
|
||||
Vector3
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
var Sky = function () {
|
||||
|
||||
var shader = Sky.SkyShader;
|
||||
|
||||
var material = new ShaderMaterial( {
|
||||
name: 'SkyShader',
|
||||
fragmentShader: shader.fragmentShader,
|
||||
vertexShader: shader.vertexShader,
|
||||
uniforms: UniformsUtils.clone( shader.uniforms ),
|
||||
side: BackSide,
|
||||
depthWrite: false
|
||||
} );
|
||||
|
||||
Mesh.call( this, new BoxGeometry( 1, 1, 1 ), material );
|
||||
|
||||
};
|
||||
|
||||
Sky.prototype = Object.create( Mesh.prototype );
|
||||
|
||||
Sky.SkyShader = {
|
||||
|
||||
uniforms: {
|
||||
'turbidity': { value: 2 },
|
||||
'rayleigh': { value: 1 },
|
||||
'mieCoefficient': { value: 0.005 },
|
||||
'mieDirectionalG': { value: 0.8 },
|
||||
'sunPosition': { value: new Vector3() },
|
||||
'up': { value: new 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' )
|
||||
|
||||
};
|
||||
|
||||
export { Sky };
|
31
node_modules/three/examples/jsm/objects/Water.d.ts
generated
vendored
Normal file
31
node_modules/three/examples/jsm/objects/Water.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
import {
|
||||
BufferGeometry,
|
||||
Color,
|
||||
Geometry,
|
||||
Mesh,
|
||||
Side,
|
||||
Texture,
|
||||
Vector3
|
||||
} from '../../../src/Three';
|
||||
|
||||
export interface WaterOptions {
|
||||
textureWidth?: number;
|
||||
textureHeight?: number;
|
||||
clipBias?: number;
|
||||
alpha?: number;
|
||||
time?: number;
|
||||
waterNormals?: Texture;
|
||||
sunDirection?: Vector3;
|
||||
sunColor?: Color | string | number;
|
||||
waterColor?: Color | string | number;
|
||||
eye?: Vector3;
|
||||
distortionScale?: number;
|
||||
side?: Side;
|
||||
fog?: boolean;
|
||||
}
|
||||
|
||||
export class Water extends Mesh {
|
||||
|
||||
constructor( geometry: Geometry | BufferGeometry, options: WaterOptions );
|
||||
|
||||
}
|
365
node_modules/three/examples/jsm/objects/Water.js
generated
vendored
Normal file
365
node_modules/three/examples/jsm/objects/Water.js
generated
vendored
Normal file
|
@ -0,0 +1,365 @@
|
|||
import {
|
||||
Color,
|
||||
FrontSide,
|
||||
LinearEncoding,
|
||||
LinearFilter,
|
||||
MathUtils,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
NoToneMapping,
|
||||
PerspectiveCamera,
|
||||
Plane,
|
||||
RGBFormat,
|
||||
ShaderMaterial,
|
||||
UniformsLib,
|
||||
UniformsUtils,
|
||||
Vector3,
|
||||
Vector4,
|
||||
WebGLRenderTarget
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
var Water = function ( geometry, options ) {
|
||||
|
||||
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 Vector3( 0.70707, 0.70707, 0.0 );
|
||||
var sunColor = new Color( options.sunColor !== undefined ? options.sunColor : 0xffffff );
|
||||
var waterColor = new Color( options.waterColor !== undefined ? options.waterColor : 0x7F7F7F );
|
||||
var eye = options.eye !== undefined ? options.eye : new Vector3( 0, 0, 0 );
|
||||
var distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;
|
||||
var side = options.side !== undefined ? options.side : FrontSide;
|
||||
var fog = options.fog !== undefined ? options.fog : false;
|
||||
|
||||
//
|
||||
|
||||
var mirrorPlane = new Plane();
|
||||
var normal = new Vector3();
|
||||
var mirrorWorldPosition = new Vector3();
|
||||
var cameraWorldPosition = new Vector3();
|
||||
var rotationMatrix = new Matrix4();
|
||||
var lookAtPosition = new Vector3( 0, 0, - 1 );
|
||||
var clipPlane = new Vector4();
|
||||
|
||||
var view = new Vector3();
|
||||
var target = new Vector3();
|
||||
var q = new Vector4();
|
||||
|
||||
var textureMatrix = new Matrix4();
|
||||
|
||||
var mirrorCamera = new PerspectiveCamera();
|
||||
|
||||
var parameters = {
|
||||
minFilter: LinearFilter,
|
||||
magFilter: LinearFilter,
|
||||
format: RGBFormat
|
||||
};
|
||||
|
||||
var renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
|
||||
|
||||
if ( ! MathUtils.isPowerOfTwo( textureWidth ) || ! MathUtils.isPowerOfTwo( textureHeight ) ) {
|
||||
|
||||
renderTarget.texture.generateMipmaps = false;
|
||||
|
||||
}
|
||||
|
||||
var mirrorShader = {
|
||||
|
||||
uniforms: UniformsUtils.merge( [
|
||||
UniformsLib[ 'fog' ],
|
||||
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 Matrix4() },
|
||||
'sunColor': { value: new Color( 0x7F7F7F ) },
|
||||
'sunDirection': { value: new Vector3( 0.70707, 0.70707, 0 ) },
|
||||
'eye': { value: new Vector3() },
|
||||
'waterColor': { value: new 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 ShaderMaterial( {
|
||||
fragmentShader: mirrorShader.fragmentShader,
|
||||
vertexShader: mirrorShader.vertexShader,
|
||||
uniforms: 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 !== LinearEncoding ) {
|
||||
|
||||
console.warn( 'THREE.Water: WebGLRenderer must use LinearEncoding as outputEncoding.' );
|
||||
scope.onBeforeRender = function () {};
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( renderer.toneMapping !== 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 );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Water.prototype = Object.create( Mesh.prototype );
|
||||
Water.prototype.constructor = Water;
|
||||
|
||||
export { Water };
|
31
node_modules/three/examples/jsm/objects/Water2.d.ts
generated
vendored
Normal file
31
node_modules/three/examples/jsm/objects/Water2.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
import {
|
||||
BufferGeometry,
|
||||
Color,
|
||||
Geometry,
|
||||
Mesh,
|
||||
Texture,
|
||||
TextureEncoding,
|
||||
Vector2
|
||||
} from '../../../src/Three';
|
||||
|
||||
export interface WaterOptions {
|
||||
color?: Color | string | number;
|
||||
textureWidth?: number;
|
||||
textureHeight?: number;
|
||||
clipBias?: number;
|
||||
flowDirection?: Vector2;
|
||||
flowSpeed?: number;
|
||||
reflectivity?: number;
|
||||
scale?: number;
|
||||
shader?: object;
|
||||
flowMap?: Texture;
|
||||
normalMap0?: Texture;
|
||||
normalMap1?: Texture;
|
||||
encoding?: TextureEncoding;
|
||||
}
|
||||
|
||||
export class Water extends Mesh {
|
||||
|
||||
constructor( geometry: Geometry | BufferGeometry, options: WaterOptions );
|
||||
|
||||
}
|
364
node_modules/three/examples/jsm/objects/Water2.js
generated
vendored
Normal file
364
node_modules/three/examples/jsm/objects/Water2.js
generated
vendored
Normal file
|
@ -0,0 +1,364 @@
|
|||
import {
|
||||
Clock,
|
||||
Color,
|
||||
LinearEncoding,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
RepeatWrapping,
|
||||
ShaderMaterial,
|
||||
TextureLoader,
|
||||
UniformsLib,
|
||||
UniformsUtils,
|
||||
Vector2,
|
||||
Vector4
|
||||
} from '../../../build/three.module.js';
|
||||
import { Reflector } from '../objects/Reflector.js';
|
||||
import { Refractor } from '../objects/Refractor.js';
|
||||
|
||||
/**
|
||||
* References:
|
||||
* http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf
|
||||
* http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html
|
||||
*
|
||||
*/
|
||||
|
||||
var Water = function ( geometry, options ) {
|
||||
|
||||
Mesh.call( this, geometry );
|
||||
|
||||
this.type = 'Water';
|
||||
|
||||
var scope = this;
|
||||
|
||||
options = options || {};
|
||||
|
||||
var color = ( options.color !== undefined ) ? new Color( options.color ) : new Color( 0xFFFFFF );
|
||||
var textureWidth = options.textureWidth || 512;
|
||||
var textureHeight = options.textureHeight || 512;
|
||||
var clipBias = options.clipBias || 0;
|
||||
var flowDirection = options.flowDirection || new Vector2( 1, 0 );
|
||||
var flowSpeed = options.flowSpeed || 0.03;
|
||||
var reflectivity = options.reflectivity || 0.02;
|
||||
var scale = options.scale || 1;
|
||||
var shader = options.shader || Water.WaterShader;
|
||||
var encoding = options.encoding !== undefined ? options.encoding : LinearEncoding;
|
||||
|
||||
var textureLoader = new 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 Matrix4();
|
||||
var clock = new Clock();
|
||||
|
||||
// internal components
|
||||
|
||||
if ( Reflector === undefined ) {
|
||||
|
||||
console.error( 'THREE.Water: Required component Reflector not found.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( Refractor === undefined ) {
|
||||
|
||||
console.error( 'THREE.Water: Required component Refractor not found.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var reflector = new Reflector( geometry, {
|
||||
textureWidth: textureWidth,
|
||||
textureHeight: textureHeight,
|
||||
clipBias: clipBias,
|
||||
encoding: encoding
|
||||
} );
|
||||
|
||||
var refractor = new Refractor( geometry, {
|
||||
textureWidth: textureWidth,
|
||||
textureHeight: textureHeight,
|
||||
clipBias: clipBias,
|
||||
encoding: encoding
|
||||
} );
|
||||
|
||||
reflector.matrixAutoUpdate = false;
|
||||
refractor.matrixAutoUpdate = false;
|
||||
|
||||
// material
|
||||
|
||||
this.material = new ShaderMaterial( {
|
||||
uniforms: UniformsUtils.merge( [
|
||||
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 = RepeatWrapping;
|
||||
normalMap1.wrapS = normalMap1.wrapT = 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;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Water.prototype = Object.create( Mesh.prototype );
|
||||
Water.prototype.constructor = Water;
|
||||
|
||||
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 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' )
|
||||
};
|
||||
|
||||
export { Water };
|
Loading…
Add table
Add a link
Reference in a new issue