DepthPassPlugin.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. _lights, _webglObjects, _webglObjectsImmediate,
  10. _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
  11. _frustum = new THREE.Frustum(),
  12. _projScreenMatrix = new THREE.Matrix4(),
  13. _renderList = [];
  14. this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {
  15. _gl = renderer.context;
  16. _renderer = renderer;
  17. _lights = lights;
  18. _webglObjects = webglObjects;
  19. _webglObjectsImmediate = webglObjectsImmediate;
  20. var depthShader = THREE.ShaderLib[ "depthRGBA" ];
  21. var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
  22. _depthMaterial = new THREE.ShaderMaterial( {
  23. fragmentShader: depthShader.fragmentShader,
  24. vertexShader: depthShader.vertexShader,
  25. uniforms: depthUniforms
  26. } );
  27. _depthMaterialMorph = new THREE.ShaderMaterial( {
  28. fragmentShader: depthShader.fragmentShader,
  29. vertexShader: depthShader.vertexShader,
  30. uniforms: depthUniforms,
  31. morphTargets: true
  32. } );
  33. _depthMaterialSkin = new THREE.ShaderMaterial( {
  34. fragmentShader: depthShader.fragmentShader,
  35. vertexShader: depthShader.vertexShader,
  36. uniforms: depthUniforms,
  37. skinning: true
  38. } );
  39. _depthMaterialMorphSkin = new THREE.ShaderMaterial( {
  40. fragmentShader: depthShader.fragmentShader,
  41. vertexShader: depthShader.vertexShader,
  42. uniforms: depthUniforms,
  43. morphTargets: true,
  44. skinning: true
  45. } );
  46. _depthMaterial._shadowPass = true;
  47. _depthMaterialMorph._shadowPass = true;
  48. _depthMaterialSkin._shadowPass = true;
  49. _depthMaterialMorphSkin._shadowPass = true;
  50. };
  51. this.render = function ( scene, camera ) {
  52. if ( ! this.enabled ) return;
  53. this.update( scene, camera );
  54. };
  55. this.update = function ( scene, camera ) {
  56. var i, il, j, jl, n,
  57. program, buffer, material,
  58. webglObject, object, light,
  59. renderList,
  60. fog = null;
  61. // set GL state for depth map
  62. _gl.clearColor( 1, 1, 1, 1 );
  63. _gl.disable( _gl.BLEND );
  64. _renderer.setDepthTest( true );
  65. // update scene
  66. if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
  67. // update camera matrices and frustum
  68. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  69. _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
  70. _frustum.setFromMatrix( _projScreenMatrix );
  71. // render depth map
  72. _renderer.setRenderTarget( this.renderTarget );
  73. _renderer.clear();
  74. // set object matrices & frustum culling
  75. _renderList.length = 0;
  76. projectObject(scene, scene, camera);
  77. // render regular objects
  78. var objectMaterial, useMorphing, useSkinning;
  79. for ( j = 0, jl = _renderList.length; j < jl; j ++ ) {
  80. webglObject = _renderList[ j ];
  81. object = webglObject.object;
  82. buffer = webglObject.buffer;
  83. // todo: create proper depth material for particles
  84. if ( object instanceof THREE.PointCloud && ! object.customDepthMaterial ) continue;
  85. objectMaterial = getObjectMaterial( object );
  86. if ( objectMaterial ) _renderer.setMaterialFaces( object.material );
  87. useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
  88. useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;
  89. if ( object.customDepthMaterial ) {
  90. material = object.customDepthMaterial;
  91. } else if ( useSkinning ) {
  92. material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;
  93. } else if ( useMorphing ) {
  94. material = _depthMaterialMorph;
  95. } else {
  96. material = _depthMaterial;
  97. }
  98. if ( buffer instanceof THREE.BufferGeometry ) {
  99. _renderer.renderBufferDirect( camera, _lights, fog, material, buffer, object );
  100. } else {
  101. _renderer.renderBuffer( camera, _lights, fog, material, buffer, object );
  102. }
  103. }
  104. // set matrices and render immediate objects
  105. for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {
  106. webglObject = _webglObjectsImmediate[ j ];
  107. object = webglObject.object;
  108. if ( object.visible ) {
  109. object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
  110. _renderer.renderImmediateObject( camera, _lights, fog, _depthMaterial, object );
  111. }
  112. }
  113. // restore GL state
  114. var clearColor = _renderer.getClearColor(),
  115. clearAlpha = _renderer.getClearAlpha();
  116. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  117. _gl.enable( _gl.BLEND );
  118. };
  119. function projectObject(scene, object,camera) {
  120. if ( object.visible ) {
  121. var webglObjects = _webglObjects[object.id];
  122. if (webglObjects && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {
  123. for (var i = 0, l = webglObjects.length; i < l; i ++) {
  124. var webglObject = webglObjects[i];
  125. object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
  126. _renderList.push(webglObject);
  127. }
  128. }
  129. for (var i = 0, l = object.children.length; i < l; i ++) {
  130. projectObject(scene, object.children[i], camera);
  131. }
  132. }
  133. }
  134. // For the moment just ignore objects that have multiple materials with different animation methods
  135. // Only the first material will be taken into account for deciding which depth material to use
  136. function getObjectMaterial( object ) {
  137. return object.material instanceof THREE.MeshFaceMaterial
  138. ? object.material.materials[ 0 ]
  139. : object.material;
  140. };
  141. };