Skip to content

Commit 49f14b8

Browse files
committed
Refactored shadow maps to store shadow parameters and data in SpotLight.
This allows to have different shadow map parameters for different lights, also it's easier to access parameters for tweaking / debugging. Changes: renderer.shadowMapWidth => spotLight.shadowMapWidth renderer.shadowMapHeight => spotLight.shadowMapHeight renderer.shadowMapBias => spotLight.shadowBias renderer.shadowMapDarkness => spotLight.shadowDarkness renderer.shadowCameraNear => spotLight.shadowCameraNear renderer.shadowCameraFar => spotLight.shadowCameraFar renderer.shadowCameraFov => spotLight.shadowCameraFov Also added new uniform type "v2v" for array of Vector2 (to support per-light sizes of shadow maps).
1 parent 9458d47 commit 49f14b8

12 files changed

+762
-719
lines changed

build/Three.js

Lines changed: 327 additions & 326 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/custom/ThreeExtras.js

Lines changed: 169 additions & 169 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/custom/ThreeWebGL.js

Lines changed: 105 additions & 104 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/webgl_interactive_draggablecubes.html

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@
4848
var light = new THREE.SpotLight( 0xffffff, 1.5 );
4949
light.position.set( 0, 500, 2000 );
5050
light.castShadow = true;
51+
52+
light.shadowCameraNear = 200;
53+
light.shadowCameraFar = camera.far;
54+
light.shadowCameraFov = 50;
55+
56+
light.shadowBias = -0.00022;
57+
light.shadowDarkness = 0.5;
58+
59+
light.shadowMapWidth = 1024;
60+
light.shadowMapHeight = 1024;
61+
5162
scene.add( light );
5263

5364
var geometry = new THREE.CubeGeometry( 40, 40, 40 );
@@ -93,15 +104,6 @@
93104
renderer.shadowMapEnabled = true;
94105
renderer.shadowMapSoft = true;
95106

96-
renderer.shadowCameraNear = 200;
97-
renderer.shadowCameraFar = camera.far;
98-
renderer.shadowCameraFov = 50;
99-
100-
renderer.shadowMapBias = -0.00022;
101-
renderer.shadowMapDarkness = 0.5;
102-
renderer.shadowMapWidth = 1024;
103-
renderer.shadowMapHeight = 1024;
104-
105107
container.appendChild( renderer.domElement );
106108

107109
var info = document.createElement( 'div' );

examples/webgl_materials_cubemap_dynamic.html

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@
167167
spotLight.position.set( 0, 1800, 1500 );
168168
spotLight.target.position.set( 0, 0, 0 );
169169
spotLight.castShadow = true;
170+
171+
spotLight.shadowCameraNear = 100;
172+
spotLight.shadowCameraFar = camera.far;
173+
spotLight.shadowCameraFov = 50;
174+
175+
spotLight.shadowBias = -0.00125;
176+
spotLight.shadowDarkness = 0.5;
177+
spotLight.shadowMapWidth = SHADOW_MAP_WIDTH;
178+
spotLight.shadowMapHeight = SHADOW_MAP_HEIGHT;
179+
170180
scene.add( spotLight );
171181

172182
directionalLight2 = new THREE.PointLight( 0xff9900, 0.25 );
@@ -189,16 +199,7 @@
189199

190200
// SHADOW
191201

192-
renderer.shadowCameraNear = 100;
193-
renderer.shadowCameraFar = camera.far;
194-
renderer.shadowCameraFov = 50;
195-
196-
renderer.shadowMapBias = -0.00125;
197-
renderer.shadowMapDarkness = 0.5;
198-
renderer.shadowMapWidth = SHADOW_MAP_WIDTH;
199-
renderer.shadowMapHeight = SHADOW_MAP_HEIGHT;
200202
renderer.shadowMapCullFrontFaces = false;
201-
202203
renderer.shadowMapEnabled = true;
203204

204205
// STATS

examples/webgl_materials_normalmap.html

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
var mesh, zmesh, lightMesh, geometry;
6565
var mesh1, mesh2;
6666

67-
var directionalLight, pointLight, ambientLight;
67+
var spotLight, pointLight, ambientLight;
6868

6969
var mouseX = 0;
7070
var mouseY = 0;
@@ -113,10 +113,15 @@
113113
pointLight3.distance = 2000;
114114
scene.add( pointLight3 );
115115

116-
directionalLight = new THREE.SpotLight( 0xaaaaaa );
117-
directionalLight.position.set( 1000, 500, 1000 );
118-
directionalLight.castShadow = true;
119-
scene.add( directionalLight );
116+
spotLight = new THREE.SpotLight( 0xaaaaaa );
117+
spotLight.position.set( 1000, 500, 1000 );
118+
spotLight.castShadow = true;
119+
spotLight.shadowCameraNear = 500;
120+
spotLight.shadowCameraFov = 70;
121+
spotLight.shadowBias = 0.001;
122+
spotLight.shadowMapWidth = 1024;
123+
spotLight.shadowMapHeight = 1024;
124+
scene.add( spotLight );
120125

121126
directionalLight2 = new THREE.DirectionalLight( 0xaaff33, 0 );
122127
directionalLight2.position.set( -1, 1, 0.5 ).normalize();
@@ -205,12 +210,6 @@
205210

206211
//
207212

208-
renderer.shadowCameraNear = 500;
209-
renderer.shadowCameraFov = 70;
210-
renderer.shadowMapBias = 0.001;
211-
renderer.shadowMapWidth = 1024;
212-
renderer.shadowMapHeight = 1024;
213-
214213
renderer.shadowMapEnabled = true;
215214
renderer.shadowMapSoft = true;
216215

examples/webgl_shading_physical.html

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,13 @@
316316

317317
sunLight = new THREE.SpotLight( 0xffffff, sunIntensity );
318318
sunLight.position.set( 1000, 2000, 1000 );
319+
319320
sunLight.castShadow = true;
321+
322+
sunLight.shadowDarkness = 0.5 * sunIntensity;
323+
sunLight.shadowBias = 0;
324+
sunLight.shadowCameraNear = 50;
325+
320326
scene.add( sunLight );
321327

322328
// RENDERER
@@ -333,14 +339,10 @@
333339

334340
container.appendChild( renderer.domElement );
335341

336-
337342
//
338343

339344
renderer.shadowMapAutoUpdate = false;
340345
renderer.shadowMapEnabled = true;
341-
renderer.shadowMapDarkness = 0.5 * sunIntensity;
342-
renderer.shadowMapBias = 0.0;
343-
renderer.shadowCameraNear = 50;
344346

345347
//
346348

@@ -498,7 +500,7 @@
498500

499501
pointLight.color.setHSV( 0.1, THREE.Math.mapLinear( parameters.control, 0, 100, 0.99, 0 ), 0.9 );
500502

501-
renderer.shadowMapDarkness = 0.5 * sunLight.intensity;
503+
sunLight.shadowDarkness = 0.4 * sunLight.intensity;
502504

503505
// render shadow map
504506

examples/webgl_shadowmap.html

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,19 @@
106106
light = new THREE.SpotLight( 0xffffff );
107107
light.position.set( 0, 1500, 1000 );
108108
light.target.position.set( 0, 0, 0 );
109+
109110
light.castShadow = true;
111+
112+
light.shadowCameraNear = 100;
113+
light.shadowCameraFar = camera.far;
114+
light.shadowCameraFov = 50;
115+
116+
light.shadowBias = 0.0001;
117+
light.shadowDarkness = 0.5;
118+
119+
light.shadowMapWidth = SHADOW_MAP_WIDTH;
120+
light.shadowMapHeight = SHADOW_MAP_HEIGHT;
121+
110122
scene.add( light );
111123

112124
createHUD();
@@ -123,14 +135,7 @@
123135
renderer.setClearColor( scene.fog.color, 1 );
124136
renderer.autoClear = false;
125137

126-
renderer.shadowCameraNear = 100;
127-
renderer.shadowCameraFar = camera.far;
128-
renderer.shadowCameraFov = 50;
129-
130-
renderer.shadowMapBias = 0.0001;
131-
renderer.shadowMapDarkness = 0.5;
132-
renderer.shadowMapWidth = SHADOW_MAP_WIDTH;
133-
renderer.shadowMapHeight = SHADOW_MAP_HEIGHT;
138+
//
134139

135140
renderer.shadowMapEnabled = true;
136141
renderer.shadowMapSoft = true;

src/extras/plugins/ShadowMapPlugin.js

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,11 @@ THREE.ShadowMapPlugin = function ( ) {
66

77
var _gl,
88
_renderer,
9-
_cameraLight,
109
_depthMaterial, _depthMaterialMorph,
1110

1211
_frustum = new THREE.Frustum(),
1312
_projScreenMatrix = new THREE.Matrix4();
1413

15-
this.shadowMatrix = [];
16-
this.shadowMap = [];
17-
1814
this.init = function ( renderer ) {
1915

2016
_gl = renderer.context;
@@ -43,22 +39,14 @@ THREE.ShadowMapPlugin = function ( ) {
4339

4440
var i, il, j, jl,
4541

46-
shadowMap, shadowMatrix,
42+
shadowMap, shadowMatrix, shadowCamera,
4743
program, buffer, material,
4844
webglObject, object, light,
4945
renderList,
5046

51-
shadowIndex = 0,
52-
5347
lights = scene.lights,
5448
fog = null;
5549

56-
if ( ! _cameraLight ) {
57-
58-
_cameraLight = new THREE.PerspectiveCamera( _renderer.shadowCameraFov, _renderer.shadowMapWidth / _renderer.shadowMapHeight, _renderer.shadowCameraNear, _renderer.shadowCameraFar );
59-
60-
}
61-
6250
// set GL state for depth map
6351

6452
_gl.clearColor( 1, 1, 1, 1 );
@@ -75,30 +63,34 @@ THREE.ShadowMapPlugin = function ( ) {
7563

7664
if ( light.castShadow && light instanceof THREE.SpotLight ) {
7765

78-
if ( ! this.shadowMap[ shadowIndex ] ) {
66+
if ( ! light.shadowMap ) {
7967

8068
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
8169

82-
this.shadowMap[ shadowIndex ] = new THREE.WebGLRenderTarget( _renderer.shadowMapWidth, _renderer.shadowMapHeight, pars );
83-
this.shadowMatrix[ shadowIndex ] = new THREE.Matrix4();
70+
light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
71+
light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
72+
73+
light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
74+
light.shadowMatrix = new THREE.Matrix4();
8475

8576
}
8677

87-
shadowMap = this.shadowMap[ shadowIndex ];
88-
shadowMatrix = this.shadowMatrix[ shadowIndex ];
78+
shadowMap = light.shadowMap;
79+
shadowMatrix = light.shadowMatrix;
80+
shadowCamera = light.shadowCamera;
8981

90-
_cameraLight.position.copy( light.position );
91-
_cameraLight.lookAt( light.target.position );
82+
shadowCamera.position.copy( light.position );
83+
shadowCamera.lookAt( light.target.position );
9284

93-
if ( _cameraLight.parent == null ) {
85+
if ( shadowCamera.parent == null ) {
9486

95-
scene.add( _cameraLight );
87+
scene.add( shadowCamera );
9688

9789
if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
9890

9991
}
10092

101-
_cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
93+
shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
10294

10395
// compute shadow matrix
10496

@@ -107,18 +99,18 @@ THREE.ShadowMapPlugin = function ( ) {
10799
0.0, 0.0, 0.5, 0.5,
108100
0.0, 0.0, 0.0, 1.0 );
109101

110-
shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
111-
shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
102+
shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
103+
shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
112104

113105
// render shadow map
114106

115-
if ( ! _cameraLight._viewMatrixArray ) _cameraLight._viewMatrixArray = new Float32Array( 16 );
116-
_cameraLight.matrixWorldInverse.flattenToArray( _cameraLight._viewMatrixArray );
107+
if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
108+
shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
117109

118-
if ( ! _cameraLight._projectionMatrixArray ) _cameraLight._projectionMatrixArray = new Float32Array( 16 );
119-
_cameraLight.projectionMatrix.flattenToArray( _cameraLight._projectionMatrixArray );
110+
if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
111+
shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
120112

121-
_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
113+
_projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
122114
_frustum.setFromMatrix( _projScreenMatrix );
123115

124116
_renderer.setRenderTarget( shadowMap );
@@ -140,7 +132,7 @@ THREE.ShadowMapPlugin = function ( ) {
140132
if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
141133

142134
object.matrixWorld.flattenToArray( object._objectMatrixArray );
143-
object._modelViewMatrix.multiplyToArray( _cameraLight.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
135+
object._modelViewMatrix.multiplyToArray( shadowCamera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
144136

145137
webglObject.render = true;
146138

@@ -179,11 +171,11 @@ THREE.ShadowMapPlugin = function ( ) {
179171

180172
if ( buffer instanceof THREE.BufferGeometry ) {
181173

182-
_renderer.renderBufferDirect( _cameraLight, lights, fog, material, buffer, object );
174+
_renderer.renderBufferDirect( shadowCamera, lights, fog, material, buffer, object );
183175

184176
} else {
185177

186-
_renderer.renderBuffer( _cameraLight, lights, fog, material, buffer, object );
178+
_renderer.renderBuffer( shadowCamera, lights, fog, material, buffer, object );
187179

188180
}
189181

@@ -208,16 +200,14 @@ THREE.ShadowMapPlugin = function ( ) {
208200

209201
}
210202

211-
object._modelViewMatrix.multiplyToArray( _cameraLight.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
203+
object._modelViewMatrix.multiplyToArray( shadowCamera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
212204

213-
_renderer.renderImmediateObject( _cameraLight, lights, fog, _depthMaterial, object );
205+
_renderer.renderImmediateObject( shadowCamera, lights, fog, _depthMaterial, object );
214206

215207
}
216208

217209
}
218210

219-
shadowIndex ++;
220-
221211
}
222212

223213
}

src/lights/SpotLight.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@ THREE.SpotLight = function ( hex, intensity, distance, castShadow ) {
1515
this.castShadow = ( castShadow !== undefined ) ? castShadow : false;
1616
this.onlyShadow = false;
1717

18+
//
19+
20+
this.shadowCameraNear = 50;
21+
this.shadowCameraFar = 5000;
22+
this.shadowCameraFov = 50;
23+
24+
this.shadowBias = 0;
25+
this.shadowDarkness = 0.5;
26+
27+
this.shadowMapWidth = 512;
28+
this.shadowMapHeight = 512;
29+
30+
//
31+
32+
this.shadowMap = null;
33+
this.shadowMapSize = null;
34+
this.shadowCamera = null;
35+
this.shadowMatrix = null;
36+
1837
};
1938

2039
THREE.SpotLight.prototype = new THREE.Light();

0 commit comments

Comments
 (0)