DepthPassPlugin.js 5.7 KB

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