ShadowMapPlugin.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. THREE.ShadowMapPlugin = function ( ) {
  5. var _gl,
  6. _renderer,
  7. _cameraLight,
  8. _depthMaterial, _depthMaterialMorph,
  9. _frustum = new THREE.Frustum(),
  10. _projScreenMatrix = new THREE.Matrix4();
  11. this.shadowMatrix = [];
  12. this.shadowMap = [];
  13. this.init = function ( renderer ) {
  14. _gl = renderer.context;
  15. _renderer = renderer;
  16. var depthShader = THREE.ShaderLib[ "depthRGBA" ];
  17. var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
  18. _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
  19. _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
  20. _depthMaterial._shadowPass = true;
  21. _depthMaterialMorph._shadowPass = true;
  22. };
  23. this.render = function ( scene, camera ) {
  24. if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
  25. this.update( scene, camera );
  26. };
  27. this.update = function ( scene, camera ) {
  28. var i, il, j, jl,
  29. shadowMap, shadowMatrix,
  30. program, buffer, material,
  31. webglObject, object, light,
  32. renderList,
  33. shadowIndex = 0,
  34. lights = scene.lights,
  35. fog = null;
  36. if ( ! _cameraLight ) {
  37. _cameraLight = new THREE.PerspectiveCamera( _renderer.shadowCameraFov, _renderer.shadowMapWidth / _renderer.shadowMapHeight, _renderer.shadowCameraNear, _renderer.shadowCameraFar );
  38. }
  39. // set GL state for depth map
  40. _gl.clearColor( 1, 1, 1, 1 );
  41. _gl.disable( _gl.BLEND );
  42. if ( _renderer.shadowMapCullFrontFaces ) _gl.cullFace( _gl.FRONT );
  43. _renderer.setDepthTest( true );
  44. // render depth map
  45. for ( i = 0, il = lights.length; i < il; i ++ ) {
  46. light = lights[ i ];
  47. if ( light.castShadow && light instanceof THREE.SpotLight ) {
  48. if ( ! this.shadowMap[ shadowIndex ] ) {
  49. var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
  50. this.shadowMap[ shadowIndex ] = new THREE.WebGLRenderTarget( _renderer.shadowMapWidth, _renderer.shadowMapHeight, pars );
  51. this.shadowMatrix[ shadowIndex ] = new THREE.Matrix4();
  52. }
  53. shadowMap = this.shadowMap[ shadowIndex ];
  54. shadowMatrix = this.shadowMatrix[ shadowIndex ];
  55. _cameraLight.position.copy( light.position );
  56. _cameraLight.lookAt( light.target.position );
  57. if ( _cameraLight.parent == null ) {
  58. scene.add( _cameraLight );
  59. if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
  60. }
  61. _cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
  62. // compute shadow matrix
  63. shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
  64. 0.0, 0.5, 0.0, 0.5,
  65. 0.0, 0.0, 0.5, 0.5,
  66. 0.0, 0.0, 0.0, 1.0 );
  67. shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
  68. shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
  69. // render shadow map
  70. if ( ! _cameraLight._viewMatrixArray ) _cameraLight._viewMatrixArray = new Float32Array( 16 );
  71. _cameraLight.matrixWorldInverse.flattenToArray( _cameraLight._viewMatrixArray );
  72. if ( ! _cameraLight._projectionMatrixArray ) _cameraLight._projectionMatrixArray = new Float32Array( 16 );
  73. _cameraLight.projectionMatrix.flattenToArray( _cameraLight._projectionMatrixArray );
  74. _projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
  75. _frustum.setFromMatrix( _projScreenMatrix );
  76. _renderer.setRenderTarget( shadowMap );
  77. _renderer.clear();
  78. // set matrices & frustum culling
  79. renderList = scene.__webglObjects;
  80. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  81. webglObject = renderList[ j ];
  82. object = webglObject.object;
  83. webglObject.render = false;
  84. if ( object.visible && object.castShadow ) {
  85. if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  86. object.matrixWorld.flattenToArray( object._objectMatrixArray );
  87. object._modelViewMatrix.multiplyToArray( _cameraLight.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
  88. webglObject.render = true;
  89. }
  90. }
  91. }
  92. // render regular objects
  93. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  94. webglObject = renderList[ j ];
  95. if ( webglObject.render ) {
  96. object = webglObject.object;
  97. buffer = webglObject.buffer;
  98. _renderer.setObjectFaces( object );
  99. if ( object.customDepthMaterial ) {
  100. material = object.customDepthMaterial;
  101. } else if ( object.geometry.morphTargets.length ) {
  102. material = _depthMaterialMorph;
  103. } else {
  104. material = _depthMaterial;
  105. }
  106. if ( buffer instanceof THREE.BufferGeometry ) {
  107. _renderer.renderBufferDirect( _cameraLight, lights, fog, material, buffer, object );
  108. } else {
  109. _renderer.renderBuffer( _cameraLight, lights, fog, material, buffer, object );
  110. }
  111. }
  112. }
  113. // set matrices and render immediate objects
  114. renderList = scene.__webglObjectsImmediate;
  115. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  116. webglObject = renderList[ j ];
  117. object = webglObject.object;
  118. if ( object.visible && object.castShadow ) {
  119. if( object.matrixAutoUpdate ) {
  120. object.matrixWorld.flattenToArray( object._objectMatrixArray );
  121. }
  122. object._modelViewMatrix.multiplyToArray( _cameraLight.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
  123. _renderer.renderImmediateObject( _cameraLight, lights, fog, _depthMaterial, object );
  124. }
  125. }
  126. shadowIndex ++;
  127. }
  128. }
  129. // restore GL state
  130. var clearColor = _renderer.getClearColor(),
  131. clearAlpha = _renderer.getClearAlpha();
  132. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  133. _gl.enable( _gl.BLEND );
  134. if ( _renderer.shadowMapCullFrontFaces ) _gl.cullFace( _gl.BACK );
  135. };
  136. };
粤ICP备19079148号