1 /**
2 * @author alteredq / http://alteredqualia.com/
3 */
4
5 /**@constructor*/
6 THREE.ShadowMapPlugin = function ( ) {
7
8 var _gl,
9 _renderer,
10 _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
11
12 _frustum = new THREE.Frustum(),
13 _projScreenMatrix = new THREE.Matrix4(),
14
15 _min = new THREE.Vector3(),
16 _max = new THREE.Vector3();
17
18 this.init = function ( renderer ) {
19
20 _gl = renderer.context;
21 _renderer = renderer;
22
23 var depthShader = THREE.ShaderLib[ "depthRGBA" ];
24 var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
25
26 _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
27 _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
28 _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
29 _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );
30
31 _depthMaterial._shadowPass = true;
32 _depthMaterialMorph._shadowPass = true;
33 _depthMaterialSkin._shadowPass = true;
34 _depthMaterialMorphSkin._shadowPass = true;
35
36 };
37
38 this.render = function ( scene, camera ) {
39
40 if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
41
42 this.update( scene, camera );
43
44 };
45
46 this.update = function ( scene, camera ) {
47
48 var i, il, j, jl, n,
49
50 shadowMap, shadowMatrix, shadowCamera,
51 program, buffer, material,
52 webglObject, object, light,
53 renderList,
54
55 lights = [],
56 k = 0,
57
58 fog = null;
59
60 // set GL state for depth map
61
62 _gl.clearColor( 1, 1, 1, 1 );
63 _gl.disable( _gl.BLEND );
64
65 _gl.enable( _gl.CULL_FACE );
66 _gl.frontFace( _gl.CCW );
67
68 if ( _renderer.shadowMapCullFrontFaces ) {
69
70 _gl.cullFace( _gl.FRONT );
71
72 } else {
73
74 _gl.cullFace( _gl.BACK );
75
76 }
77
78 _renderer.setDepthTest( true );
79
80 // preprocess lights
81 // - skip lights that are not casting shadows
82 // - create virtual lights for cascaded shadow maps
83
84 for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
85
86 light = scene.__lights[ i ];
87
88 if ( ! light.castShadow ) continue;
89
90 if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
91
92 for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
93
94 var virtualLight;
95
96 if ( ! light.shadowCascadeArray[ n ] ) {
97
98 virtualLight = createVirtualLight( light, n );
99 virtualLight.originalCamera = camera;
100
101 var gyro = new THREE.Gyroscope();
102 gyro.position = light.shadowCascadeOffset;
103
104 gyro.add( virtualLight );
105 gyro.add( virtualLight.target );
106
107 camera.add( gyro );
108
109 light.shadowCascadeArray[ n ] = virtualLight;
110
111 console.log( "Created virtualLight", virtualLight );
112
113 } else {
114
115 virtualLight = light.shadowCascadeArray[ n ];
116
117 }
118
119 updateVirtualLight( light, n );
120
121 lights[ k ] = virtualLight;
122 k ++;
123
124 }
125
126 } else {
127
128 lights[ k ] = light;
129 k ++;
130
131 }
132
133 }
134
135 // render depth map
136
137 for ( i = 0, il = lights.length; i < il; i ++ ) {
138
139 light = lights[ i ];
140
141 if ( ! light.shadowMap ) {
142
143 var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
144
145 light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
146 light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
147
148 light.shadowMatrix = new THREE.Matrix4();
149
150 }
151
152 if ( ! light.shadowCamera ) {
153
154 if ( light instanceof THREE.SpotLight ) {
155
156 light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
157
158 } else if ( light instanceof THREE.DirectionalLight ) {
159
160 light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
161
162 } else {
163
164 console.error( "Unsupported light type for shadow" );
165 continue;
166
167 }
168
169 scene.add( light.shadowCamera );
170
171 if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
172
173 }
174
175 if ( light.shadowCameraVisible && ! light.cameraHelper ) {
176
177 light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
178 light.shadowCamera.add( light.cameraHelper );
179
180 }
181
182 if ( light.isVirtual && virtualLight.originalCamera == camera ) {
183
184 updateShadowCamera( camera, light );
185
186 }
187
188 shadowMap = light.shadowMap;
189 shadowMatrix = light.shadowMatrix;
190 shadowCamera = light.shadowCamera;
191
192 shadowCamera.position.copy( light.matrixWorld.getPosition() );
193 shadowCamera.lookAt( light.target.matrixWorld.getPosition() );
194 shadowCamera.updateMatrixWorld();
195
196 shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
197
198 if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
199 if ( light.shadowCameraVisible ) light.cameraHelper.update();
200
201 // compute shadow matrix
202
203 shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
204 0.0, 0.5, 0.0, 0.5,
205 0.0, 0.0, 0.5, 0.5,
206 0.0, 0.0, 0.0, 1.0 );
207
208 shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
209 shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
210
211 // update camera matrices and frustum
212
213 if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
214 if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
215
216 shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
217 shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
218
219 _projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
220 _frustum.setFromMatrix( _projScreenMatrix );
221
222 // render shadow map
223
224 _renderer.setRenderTarget( shadowMap );
225 _renderer.clear();
226
227 // set object matrices & frustum culling
228
229 renderList = scene.__webglObjects;
230
231 for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
232
233 webglObject = renderList[ j ];
234 object = webglObject.object;
235
236 webglObject.render = false;
237
238 if ( object.visible && object.castShadow ) {
239
240 if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
241
242 object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
243
244 webglObject.render = true;
245
246 }
247
248 }
249
250 }
251
252 // render regular objects
253
254 var objectMaterial, useMorphing, useSkinning;
255
256 for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
257
258 webglObject = renderList[ j ];
259
260 if ( webglObject.render ) {
261
262 object = webglObject.object;
263 buffer = webglObject.buffer;
264
265 // culling is overriden globally for all objects
266 // while rendering depth map
267
268 // need to deal with MeshFaceMaterial somehow
269 // in that case just use the first of material.materials for now
270 // (proper solution would require to break objects by materials
271 // similarly to regular rendering and then set corresponding
272 // depth materials per each chunk instead of just once per object)
273
274 objectMaterial = getObjectMaterial( object );
275
276 useMorphing = object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
277 useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;
278
279 if ( object.customDepthMaterial ) {
280
281 material = object.customDepthMaterial;
282
283 } else if ( useSkinning ) {
284
285 material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;
286
287 } else if ( useMorphing ) {
288
289 material = _depthMaterialMorph;
290
291 } else {
292
293 material = _depthMaterial;
294
295 }
296
297 if ( buffer instanceof THREE.BufferGeometry ) {
298
299 _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
300
301 } else {
302
303 _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
304
305 }
306
307 }
308
309 }
310
311 // set matrices and render immediate objects
312
313 renderList = scene.__webglObjectsImmediate;
314
315 for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
316
317 webglObject = renderList[ j ];
318 object = webglObject.object;
319
320 if ( object.visible && object.castShadow ) {
321
322 object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
323
324 _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
325
326 }
327
328 }
329
330 }
331
332 // restore GL state
333
334 var clearColor = _renderer.getClearColor(),
335 clearAlpha = _renderer.getClearAlpha();
336
337 _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
338 _gl.enable( _gl.BLEND );
339
340 if ( _renderer.shadowMapCullFrontFaces ) {
341
342 _gl.cullFace( _gl.BACK );
343
344 }
345
346 };
347
348 function createVirtualLight( light, cascade ) {
349
350 var virtualLight = new THREE.DirectionalLight();
351
352 virtualLight.isVirtual = true;
353
354 virtualLight.onlyShadow = true;
355 virtualLight.castShadow = true;
356
357 virtualLight.shadowCameraNear = light.shadowCameraNear;
358 virtualLight.shadowCameraFar = light.shadowCameraFar;
359
360 virtualLight.shadowCameraLeft = light.shadowCameraLeft;
361 virtualLight.shadowCameraRight = light.shadowCameraRight;
362 virtualLight.shadowCameraBottom = light.shadowCameraBottom;
363 virtualLight.shadowCameraTop = light.shadowCameraTop;
364
365 virtualLight.shadowCameraVisible = light.shadowCameraVisible;
366
367 virtualLight.shadowDarkness = light.shadowDarkness;
368
369 virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
370 virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
371 virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
372
373 virtualLight.pointsWorld = [];
374 virtualLight.pointsFrustum = [];
375
376 var pointsWorld = virtualLight.pointsWorld,
377 pointsFrustum = virtualLight.pointsFrustum;
378
379 for ( var i = 0; i < 8; i ++ ) {
380
381 pointsWorld[ i ] = new THREE.Vector3();
382 pointsFrustum[ i ] = new THREE.Vector3();
383
384 }
385
386 var nearZ = light.shadowCascadeNearZ[ cascade ];
387 var farZ = light.shadowCascadeFarZ[ cascade ];
388
389 pointsFrustum[ 0 ].set( -1, -1, nearZ );
390 pointsFrustum[ 1 ].set( 1, -1, nearZ );
391 pointsFrustum[ 2 ].set( -1, 1, nearZ );
392 pointsFrustum[ 3 ].set( 1, 1, nearZ );
393
394 pointsFrustum[ 4 ].set( -1, -1, farZ );
395 pointsFrustum[ 5 ].set( 1, -1, farZ );
396 pointsFrustum[ 6 ].set( -1, 1, farZ );
397 pointsFrustum[ 7 ].set( 1, 1, farZ );
398
399 return virtualLight;
400
401 }
402
403 // Synchronize virtual light with the original light
404
405 function updateVirtualLight( light, cascade ) {
406
407 var virtualLight = light.shadowCascadeArray[ cascade ];
408
409 virtualLight.position.copy( light.position );
410 virtualLight.target.position.copy( light.target.position );
411 virtualLight.lookAt( virtualLight.target );
412
413 virtualLight.shadowCameraVisible = light.shadowCameraVisible;
414 virtualLight.shadowDarkness = light.shadowDarkness;
415
416 virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
417
418 var nearZ = light.shadowCascadeNearZ[ cascade ];
419 var farZ = light.shadowCascadeFarZ[ cascade ];
420
421 var pointsFrustum = virtualLight.pointsFrustum;
422
423 pointsFrustum[ 0 ].z = nearZ;
424 pointsFrustum[ 1 ].z = nearZ;
425 pointsFrustum[ 2 ].z = nearZ;
426 pointsFrustum[ 3 ].z = nearZ;
427
428 pointsFrustum[ 4 ].z = farZ;
429 pointsFrustum[ 5 ].z = farZ;
430 pointsFrustum[ 6 ].z = farZ;
431 pointsFrustum[ 7 ].z = farZ;
432
433 }
434
435 // Fit shadow camera's ortho frustum to camera frustum
436
437 function updateShadowCamera( camera, light ) {
438
439 var shadowCamera = light.shadowCamera,
440 pointsFrustum = light.pointsFrustum,
441 pointsWorld = light.pointsWorld;
442
443 _min.set( Infinity, Infinity, Infinity );
444 _max.set( -Infinity, -Infinity, -Infinity );
445
446 for ( var i = 0; i < 8; i ++ ) {
447
448 var p = pointsWorld[ i ];
449
450 p.copy( pointsFrustum[ i ] );
451 THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
452
453 shadowCamera.matrixWorldInverse.multiplyVector3( p );
454
455 if ( p.x < _min.x ) _min.x = p.x;
456 if ( p.x > _max.x ) _max.x = p.x;
457
458 if ( p.y < _min.y ) _min.y = p.y;
459 if ( p.y > _max.y ) _max.y = p.y;
460
461 if ( p.z < _min.z ) _min.z = p.z;
462 if ( p.z > _max.z ) _max.z = p.z;
463
464 }
465
466 shadowCamera.left = _min.x;
467 shadowCamera.right = _max.x;
468 shadowCamera.top = _max.y;
469 shadowCamera.bottom = _min.y;
470
471 // can't really fit near/far
472 //shadowCamera.near = _min.z;
473 //shadowCamera.far = _max.z;
474
475 shadowCamera.updateProjectionMatrix();
476
477 }
478
479 // For the moment just ignore objects that have multiple materials with different animation methods
480 // Only the first material will be taken into account for deciding which depth material to use for shadow maps
481
482 function getObjectMaterial( object ) {
483
484 return object.material instanceof THREE.MeshFaceMaterial
485 ? object.material.materials[ 0 ]
486 : object.material;
487
488 };
489
490 };
491
492 THREE.ShadowMapPlugin.__projector = new THREE.Projector();
493
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016