|
@@ -66,23 +66,12 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
this.type = THREE.PCFShadowMap;
|
|
|
this.cullFace = THREE.CullFaceFront;
|
|
|
- this.cascade = false;
|
|
|
|
|
|
this.render = function ( scene, camera ) {
|
|
|
|
|
|
if ( scope.enabled === false ) return;
|
|
|
if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
|
|
|
|
|
|
- var i, il, j, jl, n,
|
|
|
-
|
|
|
- shadowMap, shadowMatrix, shadowCamera,
|
|
|
- webglObject, object, material, light,
|
|
|
-
|
|
|
- lights = [],
|
|
|
- k = 0,
|
|
|
-
|
|
|
- fog = null;
|
|
|
-
|
|
|
// set GL state for depth map
|
|
|
|
|
|
_gl.clearColor( 1, 1, 1, 1 );
|
|
@@ -103,67 +92,14 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
_state.setDepthTest( true );
|
|
|
|
|
|
- // preprocess lights
|
|
|
- // - skip lights that are not casting shadows
|
|
|
- // - create virtual lights for cascaded shadow maps
|
|
|
+ // render depth map
|
|
|
|
|
|
- for ( i = 0, il = _lights.length; i < il; i ++ ) {
|
|
|
+ for ( var i = 0, il = _lights.length; i < il; i ++ ) {
|
|
|
|
|
|
- light = _lights[ i ];
|
|
|
+ var light = _lights[ i ];
|
|
|
|
|
|
if ( ! light.castShadow ) continue;
|
|
|
|
|
|
- if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
|
|
|
-
|
|
|
- for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
|
|
|
-
|
|
|
- var virtualLight;
|
|
|
-
|
|
|
- if ( ! light.shadowCascadeArray[ n ] ) {
|
|
|
-
|
|
|
- virtualLight = createVirtualLight( light, n );
|
|
|
- virtualLight.originalCamera = camera;
|
|
|
-
|
|
|
- var gyro = new THREE.Gyroscope();
|
|
|
- gyro.position.copy( light.shadowCascadeOffset );
|
|
|
-
|
|
|
- gyro.add( virtualLight );
|
|
|
- gyro.add( virtualLight.target );
|
|
|
-
|
|
|
- camera.add( gyro );
|
|
|
-
|
|
|
- light.shadowCascadeArray[ n ] = virtualLight;
|
|
|
-
|
|
|
- //console.log( "Created virtualLight", virtualLight );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- virtualLight = light.shadowCascadeArray[ n ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- updateVirtualLight( light, n );
|
|
|
-
|
|
|
- lights[ k ] = virtualLight;
|
|
|
- k ++;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- lights[ k ] = light;
|
|
|
- k ++;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // render depth map
|
|
|
-
|
|
|
- for ( i = 0, il = lights.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- light = lights[ i ];
|
|
|
-
|
|
|
if ( ! light.shadowMap ) {
|
|
|
|
|
|
var shadowFilter = THREE.LinearFilter;
|
|
@@ -213,15 +149,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( light.isVirtual && virtualLight.originalCamera == camera ) {
|
|
|
-
|
|
|
- updateShadowCamera( camera, light );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- shadowMap = light.shadowMap;
|
|
|
- shadowMatrix = light.shadowMatrix;
|
|
|
- shadowCamera = light.shadowCamera;
|
|
|
+ var shadowMap = light.shadowMap;
|
|
|
+ var shadowMatrix = light.shadowMatrix;
|
|
|
+ var shadowCamera = light.shadowCamera;
|
|
|
|
|
|
//
|
|
|
|
|
@@ -268,9 +198,10 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
// render regular objects
|
|
|
|
|
|
+ var webglObject, object, material;
|
|
|
var objectMaterial, useMorphing, useSkinning;
|
|
|
|
|
|
- for ( j = 0, jl = _renderList.length; j < jl; j ++ ) {
|
|
|
+ for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {
|
|
|
|
|
|
webglObject = _renderList[ j ];
|
|
|
|
|
@@ -308,7 +239,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- _renderer.renderBufferDirect( shadowCamera, _lights, fog, material, object );
|
|
|
+ _renderer.renderBufferDirect( shadowCamera, _lights, null, material, object );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -357,137 +288,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function createVirtualLight( light, cascade ) {
|
|
|
-
|
|
|
- var virtualLight = new THREE.DirectionalLight();
|
|
|
-
|
|
|
- virtualLight.isVirtual = true;
|
|
|
-
|
|
|
- virtualLight.onlyShadow = true;
|
|
|
- virtualLight.castShadow = true;
|
|
|
-
|
|
|
- virtualLight.shadowCameraNear = light.shadowCameraNear;
|
|
|
- virtualLight.shadowCameraFar = light.shadowCameraFar;
|
|
|
-
|
|
|
- virtualLight.shadowCameraLeft = light.shadowCameraLeft;
|
|
|
- virtualLight.shadowCameraRight = light.shadowCameraRight;
|
|
|
- virtualLight.shadowCameraBottom = light.shadowCameraBottom;
|
|
|
- virtualLight.shadowCameraTop = light.shadowCameraTop;
|
|
|
-
|
|
|
- virtualLight.shadowCameraVisible = light.shadowCameraVisible;
|
|
|
-
|
|
|
- virtualLight.shadowDarkness = light.shadowDarkness;
|
|
|
-
|
|
|
- virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
|
|
|
- virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
|
|
|
- virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
|
|
|
-
|
|
|
- virtualLight.pointsWorld = [];
|
|
|
- virtualLight.pointsFrustum = [];
|
|
|
-
|
|
|
- var pointsWorld = virtualLight.pointsWorld,
|
|
|
- pointsFrustum = virtualLight.pointsFrustum;
|
|
|
-
|
|
|
- for ( var i = 0; i < 8; i ++ ) {
|
|
|
-
|
|
|
- pointsWorld[ i ] = new THREE.Vector3();
|
|
|
- pointsFrustum[ i ] = new THREE.Vector3();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var nearZ = light.shadowCascadeNearZ[ cascade ];
|
|
|
- var farZ = light.shadowCascadeFarZ[ cascade ];
|
|
|
-
|
|
|
- pointsFrustum[ 0 ].set( - 1, - 1, nearZ );
|
|
|
- pointsFrustum[ 1 ].set( 1, - 1, nearZ );
|
|
|
- pointsFrustum[ 2 ].set( - 1, 1, nearZ );
|
|
|
- pointsFrustum[ 3 ].set( 1, 1, nearZ );
|
|
|
-
|
|
|
- pointsFrustum[ 4 ].set( - 1, - 1, farZ );
|
|
|
- pointsFrustum[ 5 ].set( 1, - 1, farZ );
|
|
|
- pointsFrustum[ 6 ].set( - 1, 1, farZ );
|
|
|
- pointsFrustum[ 7 ].set( 1, 1, farZ );
|
|
|
-
|
|
|
- return virtualLight;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Synchronize virtual light with the original light
|
|
|
-
|
|
|
- function updateVirtualLight( light, cascade ) {
|
|
|
-
|
|
|
- var virtualLight = light.shadowCascadeArray[ cascade ];
|
|
|
-
|
|
|
- virtualLight.position.copy( light.position );
|
|
|
- virtualLight.target.position.copy( light.target.position );
|
|
|
- virtualLight.lookAt( virtualLight.target );
|
|
|
-
|
|
|
- virtualLight.shadowCameraVisible = light.shadowCameraVisible;
|
|
|
- virtualLight.shadowDarkness = light.shadowDarkness;
|
|
|
-
|
|
|
- virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
|
|
|
-
|
|
|
- var nearZ = light.shadowCascadeNearZ[ cascade ];
|
|
|
- var farZ = light.shadowCascadeFarZ[ cascade ];
|
|
|
-
|
|
|
- var pointsFrustum = virtualLight.pointsFrustum;
|
|
|
-
|
|
|
- pointsFrustum[ 0 ].z = nearZ;
|
|
|
- pointsFrustum[ 1 ].z = nearZ;
|
|
|
- pointsFrustum[ 2 ].z = nearZ;
|
|
|
- pointsFrustum[ 3 ].z = nearZ;
|
|
|
-
|
|
|
- pointsFrustum[ 4 ].z = farZ;
|
|
|
- pointsFrustum[ 5 ].z = farZ;
|
|
|
- pointsFrustum[ 6 ].z = farZ;
|
|
|
- pointsFrustum[ 7 ].z = farZ;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Fit shadow camera's ortho frustum to camera frustum
|
|
|
-
|
|
|
- function updateShadowCamera( camera, light ) {
|
|
|
-
|
|
|
- var shadowCamera = light.shadowCamera,
|
|
|
- pointsFrustum = light.pointsFrustum,
|
|
|
- pointsWorld = light.pointsWorld;
|
|
|
-
|
|
|
- _min.set( Infinity, Infinity, Infinity );
|
|
|
- _max.set( - Infinity, - Infinity, - Infinity );
|
|
|
-
|
|
|
- for ( var i = 0; i < 8; i ++ ) {
|
|
|
-
|
|
|
- var p = pointsWorld[ i ];
|
|
|
-
|
|
|
- p.copy( pointsFrustum[ i ] );
|
|
|
- p.unproject( camera );
|
|
|
-
|
|
|
- p.applyMatrix4( shadowCamera.matrixWorldInverse );
|
|
|
-
|
|
|
- if ( p.x < _min.x ) _min.x = p.x;
|
|
|
- if ( p.x > _max.x ) _max.x = p.x;
|
|
|
-
|
|
|
- if ( p.y < _min.y ) _min.y = p.y;
|
|
|
- if ( p.y > _max.y ) _max.y = p.y;
|
|
|
-
|
|
|
- if ( p.z < _min.z ) _min.z = p.z;
|
|
|
- if ( p.z > _max.z ) _max.z = p.z;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- shadowCamera.left = _min.x;
|
|
|
- shadowCamera.right = _max.x;
|
|
|
- shadowCamera.top = _max.y;
|
|
|
- shadowCamera.bottom = _min.y;
|
|
|
-
|
|
|
- // can't really fit near/far
|
|
|
- //shadowCamera.near = _min.z;
|
|
|
- //shadowCamera.far = _max.z;
|
|
|
-
|
|
|
- shadowCamera.updateProjectionMatrix();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
// For the moment just ignore objects that have multiple materials with different animation methods
|
|
|
// Only the first material will be taken into account for deciding which depth material to use for shadow maps
|
|
|
|