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

Merge pull request #17228 from supereggbert/shadowcleanup

Shadow cleanup and refactor
......@@ -12,60 +12,18 @@
<h1>[name]</h1>
<p class="desc">
This is used internally by [page:PointLight PointLights] for calculating shadows, and also serves as
a base class for the other shadow classes.
Serves as a base class for the other shadow classes.
</p>
<h2>Example</h2>
<p>
<code>
//Create a WebGLRenderer and turn on shadows in the renderer
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
//Create a PointLight and turn on shadows for the light
var light = new THREE.PointLight( 0xffffff, 1, 100 );
light.position.set( 0, 10, 0 );
light.castShadow = true; // default false
scene.add( light );
//Set up shadow properties for the light
light.shadow.mapSize.width = 512; // default
light.shadow.mapSize.height = 512; // default
light.shadow.camera.near = 0.5; // default
light.shadow.camera.far = 500 // default
//Create a sphere that cast shadows (but does not receive them)
var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.castShadow = true; //default is false
sphere.receiveShadow = false; //default
scene.add( sphere );
//Create a plane that receives shadows (but does not cast them)
var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 );
var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } )
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.receiveShadow = true;
scene.add( plane );
//Create a helper for the shadow camera (optional)
var helper = new THREE.CameraHelper( light.shadow.camera );
scene.add( helper );
</code>
</p>
<h2>Constructor</h2>
<h3>[name]( [param:Camera camera] )</h3>
<p>
[page:Camera camera] - the light's view of the world.<br /><br />
Create a new [name]. This is not intended to be called directly - it is called
internally by [page:PointLight] or used as a base class by other light shadows.
Create a new [name]. This is not intended to be called directly - it is used as a base class by
other light shadows.
</p>
<h2>Properties</h2>
......@@ -88,7 +46,6 @@ scene.add( helper );
in shadow. Computed internally during rendering.
</p>
<h3>[property:Vector2 mapSize]</h3>
<p>
A [Page:Vector2] defining the width and height of the shadow map.<br /><br />
......@@ -118,10 +75,35 @@ scene.add( helper );
<h2>Methods</h2>
<h3>[method:Vector2 getFrameExtents]()</h3>
<p>
Used internally by the renderer to extend the shadow map to contain all viewports
</p>
<h3>[method:null updateMatrices]( [param:Light light], [param:Camera viewCamera], [param:number viewportIndex])</h3>
<p>
Update the matrices for the camera and shadow, used internally by the renderer.<br /><br />
light -- the light for which the shadow is being rendered.<br />
viewCamera -- the camera view for which the shadow is being rendered.<br />
viewportIndex -- calculates the matrix for this viewport
</p>
<h3>[method:Frustum getFrustum]()</h3>
<p>
Gets the shadow cameras frustum. Used internally by the renderer to cull objects.
</p>
<h3>[method:number getViewportCount]()</h3>
<p>
Used internally by the renderer to get the number of viewports that need to be rendered for this shadow.
</p>
<h3>[method:LightShadow copy]( [param:LightShadow source] )</h3>
<p>
Copies value of all the properties from the [page:LightShadow source] to this
SpotLight.
Light.
</p>
<h3>[method:LightShadow clone]()</h3>
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<base href="../../../../" />
<script src="list.js"></script>
<script src="page.js"></script>
<link type="text/css" rel="stylesheet" href="page.css" />
</head>
<body>
<h1>[name]</h1>
<p class="desc">
This is used internally by [page:PointLight PointLights] for calculating shadows
</p>
<h2>Example</h2>
<p>
<code>
//Create a WebGLRenderer and turn on shadows in the renderer
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
//Create a PointLight and turn on shadows for the light
var light = new THREE.PointLight( 0xffffff, 1, 100 );
light.position.set( 0, 10, 0 );
light.castShadow = true; // default false
scene.add( light );
//Set up shadow properties for the light
light.shadow.mapSize.width = 512; // default
light.shadow.mapSize.height = 512; // default
light.shadow.camera.near = 0.5; // default
light.shadow.camera.far = 500 // default
//Create a sphere that cast shadows (but does not receive them)
var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.castShadow = true; //default is false
sphere.receiveShadow = false; //default
scene.add( sphere );
//Create a plane that receives shadows (but does not cast them)
var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 );
var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } )
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.receiveShadow = true;
scene.add( plane );
//Create a helper for the shadow camera (optional)
var helper = new THREE.CameraHelper( light.shadow.camera );
scene.add( helper );
</code>
</p>
<h2>Constructor</h2>
<h3>[name]( )</h3>
<p>
Creates a new [name]. This is not intended to be called directly - it is called
internally by [page:PointLight].
</p>
<h2>Properties</h2>
<p>
See the base [page:LightShadow LightShadow] class for common properties.
</p>
<h2>Methods</h2>
<p>
See the base [page:LightShadow LightShadow] class for common methods.
</p>
<h2>Source</h2>
[link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js]
</body>
</html>
......@@ -217,8 +217,9 @@ var list = {
},
"Lights / Shadows": {
"DirectionalLightShadow": "api/en/lights/shadows/DirectionalLightShadow",
"LightShadow": "api/en/lights/shadows/LightShadow",
"PointLightShadow": "api/en/lights/shadows/PointLightShadow",
"DirectionalLightShadow": "api/en/lights/shadows/DirectionalLightShadow",
"SpotLightShadow": "api/en/lights/shadows/SpotLightShadow"
},
......
......@@ -79,13 +79,13 @@
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2 );
light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 5, 0.3 );
light.position.set( 0, 1500, 1000 );
light.target.position.set( 0, 0, 0 );
light.castShadow = true;
light.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 1200, 2500 ) );
light.shadow.camera.near = 1200;
light.shadow.camera.far = 2500;
light.shadow.bias = 0.0001;
light.shadow.mapSize.width = SHADOW_MAP_WIDTH;
......
......@@ -76,14 +76,13 @@
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2 );
light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 5, 0.3 );
light.position.set( 0, 1500, 1000 );
light.target.position.set( 0, 0, 0 );
light.castShadow = true;
light.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 700, FAR ) );
light.shadow.camera.near = 1200;
light.shadow.camera.far = 2500;
light.shadow.bias = 0.0001;
light.shadow.mapSize.width = SHADOW_MAP_WIDTH;
......
......@@ -5,7 +5,7 @@ import { OrthographicCamera } from '../cameras/OrthographicCamera.js';
* @author mrdoob / http://mrdoob.com/
*/
function DirectionalLightShadow( ) {
function DirectionalLightShadow() {
LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
......@@ -13,7 +13,26 @@ function DirectionalLightShadow( ) {
DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
constructor: DirectionalLightShadow
constructor: DirectionalLightShadow,
isDirectionalLightShadow: true,
updateMatrices: function ( light, viewCamera, viewportIndex ) {
var camera = this.camera,
lightPositionWorld = this._lightPositionWorld,
lookTarget = this._lookTarget;
lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
camera.position.copy( lightPositionWorld );
lookTarget.setFromMatrixPosition( light.target.matrixWorld );
camera.lookAt( lookTarget );
camera.updateMatrixWorld();
LightShadow.prototype.updateMatrices.call( this, light, viewCamera, viewportIndex );
}
} );
......
import { Camera } from './../cameras/Camera';
import { Light } from './../lights/Light';
import { Vector2 } from './../math/Vector2';
import { Vector4 } from './../math/Vector4';
import { Matrix4 } from './../math/Matrix4';
import { RenderTarget } from '../renderers/webgl/WebGLRenderLists';
......@@ -17,5 +19,9 @@ export class LightShadow {
copy( source: LightShadow ): this;
clone( recursive?: boolean ): this;
toJSON(): any;
getFrustum(): number;
updateMatrices( light: Light, viewCamera: Camera, viewportIndex: number ): void;
getViewport( viewportIndex: number ): Vector4;
getFrameExtents(): Vector2;
}
import { Matrix4 } from '../math/Matrix4.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
import { Frustum } from '../math/Frustum.js';
/**
* @author mrdoob / http://mrdoob.com/
......@@ -17,10 +20,72 @@ function LightShadow( camera ) {
this.map = null;
this.matrix = new Matrix4();
this._frustum = new Frustum();
this._frameExtents = new Vector2( 1, 1 );
this._viewportCount = 1;
this._viewports = [
new Vector4( 0, 0, 1, 1 )
];
}
Object.assign( LightShadow.prototype, {
_projScreenMatrix: new Matrix4(),
_lightPositionWorld: new Vector3(),
_lookTarget: new Vector3(),
getViewportCount: function () {
return this._viewportCount;
},
getFrustum: function () {
return this._frustum;
},
updateMatrices: function () {
var shadowCamera = this.camera,
shadowMatrix = this.matrix,
projScreenMatrix = this._projScreenMatrix;
projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
this._frustum.setFromMatrix( projScreenMatrix );
shadowMatrix.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
);
shadowMatrix.multiply( shadowCamera.projectionMatrix );
shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
},
getViewport: function ( viewportIndex ) {
return this._viewports[ viewportIndex ];
},
getFrameExtents: function () {
return this._frameExtents;
},
copy: function ( source ) {
this.camera = source.camera.clone();
......
import { Light } from './Light.js';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
import { LightShadow } from './LightShadow.js';
import { PointLightShadow } from './PointLightShadow.js';
/**
* @author mrdoob / http://mrdoob.com/
......@@ -33,7 +32,7 @@ function PointLight( color, intensity, distance, decay ) {
this.distance = ( distance !== undefined ) ? distance : 0;
this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );
this.shadow = new PointLightShadow();
}
......
import { PerspectiveCamera } from './../cameras/PerspectiveCamera';
import { LightShadow } from './LightShadow';
export class PointLightShadow extends LightShadow {
camera: PerspectiveCamera;
}
import { LightShadow } from './LightShadow.js';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
function PointLightShadow() {
LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) );
this._frameExtents = new Vector2( 4, 2 );
this._viewportCount = 6;
this._viewports = [
// These viewports map a cube-map onto a 2D texture with the
// following orientation:
//
// xzXZ
// y Y
//
// X - Positive x direction
// x - Negative x direction
// Y - Positive y direction
// y - Negative y direction
// Z - Positive z direction
// z - Negative z direction
// positive X
new Vector4( 2, 1, 1, 1 ),
// negative X
new Vector4( 0, 1, 1, 1 ),
// positive Z
new Vector4( 3, 1, 1, 1 ),
// negative Z
new Vector4( 1, 1, 1, 1 ),
// positive Y
new Vector4( 3, 0, 1, 1 ),
// negative Y
new Vector4( 1, 0, 1, 1 )
];
this._cubeDirections = [
new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
];
this._cubeUps = [
new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
];
}
PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
constructor: PointLightShadow,
isPointLightShadow: true,
updateMatrices: function ( light, viewCamera, viewportIndex ) {
var camera = this.camera,
shadowMatrix = this.matrix,
lightPositionWorld = this._lightPositionWorld,
lookTarget = this._lookTarget,
shadowMatrix = this.matrix,
projScreenMatrix = this._projScreenMatrix;
lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
camera.position.copy( lightPositionWorld );
lookTarget.copy( camera.position );
lookTarget.add( this._cubeDirections[ viewportIndex ] );
camera.up.copy( this._cubeUps[ viewportIndex ] );
camera.lookAt( lookTarget );
camera.updateMatrixWorld();
shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
this._frustum.setFromMatrix( projScreenMatrix );
}
} );
export { PointLightShadow };
import { PerspectiveCamera } from './../cameras/PerspectiveCamera';
import { Light } from './Light';
import { LightShadow } from './LightShadow';
export class SpotLightShadow extends LightShadow {
camera: PerspectiveCamera;
update( light: Light ): void;
}
......@@ -18,9 +18,11 @@ SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype
isSpotLightShadow: true,
update: function ( light ) {
updateMatrices: function ( light, viewCamera, viewportIndex ) {
var camera = this.camera;
var camera = this.camera,
lookTarget = this._lookTarget,
lightPositionWorld = this._lightPositionWorld;
var fov = _Math.RAD2DEG * 2 * light.angle;
var aspect = this.mapSize.width / this.mapSize.height;
......@@ -35,6 +37,15 @@ SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype
}
lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
camera.position.copy( lightPositionWorld );
lookTarget.setFromMatrixPosition( light.target.matrixWorld );
camera.lookAt( lookTarget );
camera.updateMatrixWorld();
LightShadow.prototype.updateMatrices.call( this, light, viewCamera, viewportIndex );
}
} );
......
......@@ -8,21 +8,17 @@ import { WebGLRenderTarget } from '../WebGLRenderTarget.js';
import { MeshDepthMaterial } from '../../materials/MeshDepthMaterial.js';
import { MeshDistanceMaterial } from '../../materials/MeshDistanceMaterial.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Vector2 } from '../../math/Vector2.js';
import { Matrix4 } from '../../math/Matrix4.js';
import { Frustum } from '../../math/Frustum.js';
function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
var _frustum = new Frustum(),
_projScreenMatrix = new Matrix4(),
_shadowMapSize = new Vector2(),
_maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ),
_viewportSize = new Vector2(),
_lookTarget = new Vector3(),
_lightPositionWorld = new Vector3(),
_viewport = new Vector4(),
_MorphingFlag = 1,
_SkinningFlag = 2,
......@@ -36,21 +32,6 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide };
var cubeDirections = [
new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
];
var cubeUps = [
new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
];
var cube2DViewPorts = [
new Vector4(), new Vector4(), new Vector4(),
new Vector4(), new Vector4(), new Vector4()
];
// init
for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
......@@ -69,8 +50,6 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
_depthMaterials[ i ] = depthMaterial;
//
var distanceMaterial = new MeshDistanceMaterial( {
morphTargets: useMorphing,
......@@ -82,8 +61,6 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
}
//
var scope = this;
this.enabled = false;
......@@ -114,13 +91,10 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
// render depth map
var faceCount;
for ( var i = 0, il = lights.length; i < il; i ++ ) {
var light = lights[ i ];
var shadow = light.shadow;
var isPointLight = light && light.isPointLight;
if ( shadow === undefined ) {
......@@ -129,130 +103,68 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
}
var shadowCamera = shadow.camera;
_shadowMapSize.copy( shadow.mapSize );
_shadowMapSize.min( _maxShadowMapSize );
if ( isPointLight ) {
var vpWidth = _shadowMapSize.x;
var vpHeight = _shadowMapSize.y;
// These viewports map a cube-map onto a 2D texture with the
// following orientation:
//
// xzXZ
// y Y
//
// X - Positive x direction
// x - Negative x direction
// Y - Positive y direction
// y - Negative y direction
// Z - Positive z direction
// z - Negative z direction
// positive X
cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
// negative X
cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
// positive Z
cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
// negative Z
cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
// positive Y
cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
// negative Y
cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
_shadowMapSize.x *= 4.0;
_shadowMapSize.y *= 2.0;
}
if ( shadow.map === null ) {
var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
shadow.map.texture.name = light.name + ".shadowMap";
shadowCamera.updateProjectionMatrix();
var shadowFrameExtents = shadow.getFrameExtents();
}
if ( shadow.isSpotLightShadow ) {
_shadowMapSize.multiply( shadowFrameExtents );
shadow.update( light );
}
_viewportSize.copy( shadow.mapSize );
var shadowMap = shadow.map;
var shadowMatrix = shadow.matrix;
if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) {
_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
shadowCamera.position.copy( _lightPositionWorld );
console.warn( 'THREE.WebGLShadowMap:', light, 'has shadow exceeding max texture size, reducing' );
if ( isPointLight ) {
if ( _shadowMapSize.x > maxTextureSize ) {
faceCount = 6;
_viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x );
_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
shadow.mapSize.x = _viewportSize.x;
// for point lights we set the shadow matrix to be a translation-only matrix
// equal to inverse of the light's position
}
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
if ( _shadowMapSize.y > maxTextureSize ) {
} else {
_viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y );
_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
shadow.mapSize.y = _viewportSize.y;
faceCount = 1;
}
_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
shadowCamera.lookAt( _lookTarget );
shadowCamera.updateMatrixWorld();
}
// compute shadow matrix
if ( shadow.map === null ) {
shadowMatrix.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
);
var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
shadowMatrix.multiply( shadowCamera.projectionMatrix );
shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
shadow.map.texture.name = light.name + ".shadowMap";
}
_renderer.setRenderTarget( shadowMap );
_renderer.setRenderTarget( shadow.map );
_renderer.clear();
// render shadow map for each cube face (if omni-directional) or
// run a single pass if not
var viewportCount = shadow.getViewportCount();
for ( var face = 0; face < faceCount; face ++ ) {
for ( var vp = 0; vp < viewportCount; vp ++ ) {
if ( isPointLight ) {
var viewport = shadow.getViewport( vp );
_lookTarget.copy( shadowCamera.position );
_lookTarget.add( cubeDirections[ face ] );
shadowCamera.up.copy( cubeUps[ face ] );
shadowCamera.lookAt( _lookTarget );
shadowCamera.updateMatrixWorld();
var vpDimensions = cube2DViewPorts[ face ];
_state.viewport( vpDimensions );
}
_viewport.set(
_viewportSize.x * viewport.x,
_viewportSize.y * viewport.y,
_viewportSize.x * viewport.z,
_viewportSize.y * viewport.w
);
// update camera matrices and frustum
_state.viewport( _viewport );
_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix );
shadow.updateMatrices( light, camera, vp );
// set object matrices & frustum culling
_frustum = shadow.getFrustum();
renderObject( scene, camera, shadowCamera, isPointLight );
renderObject( scene, camera, shadow.camera, light );
}
......@@ -264,7 +176,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
};
function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) {
function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar ) {
var geometry = object.geometry;
......@@ -273,7 +185,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
var materialVariants = _depthMaterials;
var customMaterial = object.customDepthMaterial;
if ( isPointLight ) {
if ( light.isPointLight ) {
materialVariants = _distanceMaterials;
customMaterial = object.customDistanceMaterial;
......@@ -362,9 +274,9 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
result.wireframeLinewidth = material.wireframeLinewidth;
result.linewidth = material.linewidth;
if ( isPointLight && result.isMeshDistanceMaterial ) {
if ( light.isPointLight && result.isMeshDistanceMaterial ) {
result.referencePosition.copy( lightPositionWorld );
result.referencePosition.setFromMatrixPosition( light.matrixWorld );
result.nearDistance = shadowCameraNear;
result.farDistance = shadowCameraFar;
......@@ -374,7 +286,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
}
function renderObject( object, camera, shadowCamera, isPointLight ) {
function renderObject( object, camera, shadowCamera, light ) {
if ( object.visible === false ) return;
......@@ -400,7 +312,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
if ( groupMaterial && groupMaterial.visible ) {
var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far );
var depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
}
......@@ -409,7 +321,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
} else if ( material.visible ) {
var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far );
var depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
}
......@@ -422,7 +334,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
for ( var i = 0, l = children.length; i < l; i ++ ) {
renderObject( children[ i ], camera, shadowCamera, isPointLight );
renderObject( children[ i ], camera, shadowCamera, light );
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册