DepthPassPlugin.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. THREE.DepthPassPlugin = function ( ) {
  5. this.enabled = false;
  6. this.renderTarget = null;
  7. var _gl,
  8. _renderer,
  9. _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
  10. _frustum = new THREE.Frustum(),
  11. _projScreenMatrix = new THREE.Matrix4();
  12. this.init = function ( renderer ) {
  13. _gl = renderer.context;
  14. _renderer = renderer;
  15. var depthShader = THREE.ShaderLib[ "depthRGBA" ];
  16. var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
  17. _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
  18. _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
  19. _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
  20. _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );
  21. _depthMaterial._shadowPass = true;
  22. _depthMaterialMorph._shadowPass = true;
  23. _depthMaterialSkin._shadowPass = true;
  24. _depthMaterialMorphSkin._shadowPass = true;
  25. };
  26. this.render = function ( scene, camera ) {
  27. if ( ! this.enabled ) return;
  28. this.update( scene, camera );
  29. };
  30. this.update = function ( scene, camera ) {
  31. var i, il, j, jl, n,
  32. program, buffer, material,
  33. webglObject, object, light,
  34. renderList,
  35. fog = null;
  36. // set GL state for depth map
  37. _gl.clearColor( 1, 1, 1, 1 );
  38. _gl.disable( _gl.BLEND );
  39. _renderer.setDepthTest( true );
  40. // update scene
  41. if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
  42. // update camera matrices and frustum
  43. if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
  44. if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
  45. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  46. camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
  47. camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
  48. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  49. _frustum.setFromMatrix( _projScreenMatrix );
  50. // render depth map
  51. _renderer.setRenderTarget( this.renderTarget );
  52. _renderer.clear();
  53. // set object matrices & frustum culling
  54. renderList = scene.__webglObjects;
  55. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  56. webglObject = renderList[ j ];
  57. object = webglObject.object;
  58. webglObject.render = false;
  59. if ( object.visible ) {
  60. if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  61. object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
  62. webglObject.render = true;
  63. }
  64. }
  65. }
  66. // render regular objects
  67. var objectMaterial, useMorphing, useSkinning;
  68. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  69. webglObject = renderList[ j ];
  70. if ( webglObject.render ) {
  71. object = webglObject.object;
  72. buffer = webglObject.buffer;
  73. // todo: create proper depth material for particles
  74. if ( object instanceof THREE.ParticleSystem && !object.customDepthMaterial ) continue;
  75. objectMaterial = getObjectMaterial( object );
  76. if ( objectMaterial ) _renderer.setMaterialFaces( object.material );
  77. useMorphing = object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
  78. useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;
  79. if ( object.customDepthMaterial ) {
  80. material = object.customDepthMaterial;
  81. } else if ( useSkinning ) {
  82. material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;
  83. } else if ( useMorphing ) {
  84. material = _depthMaterialMorph;
  85. } else {
  86. material = _depthMaterial;
  87. }
  88. if ( buffer instanceof THREE.BufferGeometry ) {
  89. _renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object );
  90. } else {
  91. _renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object );
  92. }
  93. }
  94. }
  95. // set matrices and render immediate objects
  96. renderList = scene.__webglObjectsImmediate;
  97. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  98. webglObject = renderList[ j ];
  99. object = webglObject.object;
  100. if ( object.visible ) {
  101. object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
  102. _renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object );
  103. }
  104. }
  105. // restore GL state
  106. var clearColor = _renderer.getClearColor(),
  107. clearAlpha = _renderer.getClearAlpha();
  108. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  109. _gl.enable( _gl.BLEND );
  110. };
  111. // For the moment just ignore objects that have multiple materials with different animation methods
  112. // Only the first material will be taken into account for deciding which depth material to use
  113. function getObjectMaterial( object ) {
  114. if ( object.material instanceof THREE.MeshFaceMaterial ) {
  115. if ( object.material.materials.length > 0 ) {
  116. return object.material.materials[ 0 ];
  117. } else {
  118. return object.geometry.materials[ 0 ];
  119. }
  120. } else {
  121. return object.material;
  122. }
  123. };
  124. };
粤ICP备19079148号