EffectComposer.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  5. import CopyShader from './CopyShader'
  6. import {ShaderPass} from './ShaderPass'
  7. import { MaskPass, ClearMaskPass } from './MaskPass.js';
  8. var EffectComposer = function ( renderer, renderTarget ) {
  9. this.renderer = renderer;
  10. if ( renderTarget === undefined ) {
  11. var parameters = {
  12. minFilter: THREE.LinearFilter,
  13. magFilter: THREE.LinearFilter,
  14. format: THREE.RGBAFormat,
  15. stencilBuffer: false,
  16. };
  17. var size = renderer.getDrawingBufferSize(new THREE.Vector2);
  18. renderTarget = new THREE.WebGLRenderTarget( size.width, size.height , parameters );
  19. renderTarget.texture.name = 'EffectComposer.rt1';
  20. }
  21. this.renderTarget1 = renderTarget;
  22. this.renderTarget2 = renderTarget.clone();
  23. this.renderTarget2.texture.name = 'EffectComposer.rt2';
  24. this.writeBuffer = this.renderTarget1;
  25. this.readBuffer = this.renderTarget2;
  26. this.passes = [];
  27. // dependencies
  28. /* if ( THREE.CopyShader === undefined ) {
  29. console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );
  30. }
  31. if ( THREE.ShaderPass === undefined ) {
  32. console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );
  33. } */
  34. this.copyPass = new ShaderPass( CopyShader );
  35. viewer.addEventListener('resize',(e)=>{ //readTarget的话是渲染一整张的,暂时无法一个个viewport渲染所以不用
  36. this.readTarget || this.setSize(e.viewport.resolution2.x,e.viewport.resolution2.y) //暂时假设composer渲染的viewer的viewports.length == 1
  37. })
  38. };
  39. Object.assign( EffectComposer.prototype, {
  40. swapBuffers: function () {
  41. var tmp = this.readBuffer;
  42. this.readBuffer = this.writeBuffer;
  43. this.writeBuffer = tmp;
  44. },
  45. addPass: function ( pass ) {
  46. this.passes.push( pass );
  47. var size = this.renderer.getDrawingBufferSize(new THREE.Vector2);
  48. pass.setSize( size.width, size.height );
  49. },
  50. removePass: function(pass){ //add
  51. let index = this.passes.indexOf(pass);
  52. index > -1 && this.passes.splice(index,1)
  53. },
  54. insertPass: function ( pass, index ) {
  55. this.passes.splice( index, 0, pass );
  56. },
  57. render: function ( scene, camera, viewports, renderFun ) {
  58. var maskActive = false;
  59. let passes = this.passes.filter(e=>e.enabled)
  60. var pass, i, il = passes.length;
  61. let oldTarget = this.renderer.getRenderTarget();
  62. if(this.readTarget && oldTarget){ //add 使用当前renderTarget中的像素
  63. this.setSize(oldTarget.width, oldTarget.height)//所有viewports一起渲染,整个画面 因暂时没办法一个个copy
  64. oldTarget.viewport.set(0, 0, oldTarget.width, oldTarget.height);
  65. oldTarget.scissorTest = false
  66. this.copyPass.render( scene, camera,viewports, this.renderer, this.readBuffer, oldTarget );
  67. }
  68. for ( i = 0; i < il; i ++ ) {
  69. pass = passes[ i ];
  70. //if(i == il-1)pass.renderToScreen = true//
  71. pass.render( scene, camera, viewports, this.renderer, this.writeBuffer, this.readBuffer, maskActive, renderFun );
  72. if ( pass.needsSwap ) {
  73. if ( maskActive ) {
  74. var context = this.renderer.context;
  75. context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
  76. this.copyPass.render(null,null, viewports, this.renderer, this.writeBuffer, this.readBuffer );// delta
  77. context.stencilFunc( context.EQUAL, 1, 0xffffffff );
  78. }
  79. this.swapBuffers();
  80. }
  81. if ( MaskPass !== undefined ) {
  82. if ( pass instanceof MaskPass ) {
  83. maskActive = true;
  84. } else if ( pass instanceof ClearMaskPass ) {
  85. maskActive = false;
  86. }
  87. }
  88. }
  89. this.renderer.setRenderTarget(oldTarget);
  90. //add
  91. if(!pass.renderToScreen){ //最后一个如果没有绘制到屏幕or target上
  92. this.copyPass.renderToScreen = true
  93. this.copyPass.render(null,null, viewports,this.renderer, this.writeBuffer, this.readBuffer)
  94. }
  95. },
  96. reset: function ( renderTarget ) {
  97. if ( renderTarget === undefined ) {
  98. var size = this.renderer.getDrawingBufferSize(new THREE.Vector2);
  99. renderTarget = this.renderTarget1.clone();
  100. renderTarget.setSize( size.width, size.height );
  101. }
  102. this.renderTarget1.dispose();
  103. this.renderTarget2.dispose();
  104. this.renderTarget1 = renderTarget;
  105. this.renderTarget2 = renderTarget.clone();
  106. this.writeBuffer = this.renderTarget1;
  107. this.readBuffer = this.renderTarget2;
  108. },
  109. setSize: function ( width, height, scaleRatio ) {
  110. scaleRatio = scaleRatio || this.scaleRatio || 1;
  111. //console.log('setSize', width * scaleRatio, height * scaleRatio)
  112. let maxTexWidth = 4096
  113. let w = width * scaleRatio
  114. let h = height * scaleRatio
  115. if(w > maxTexWidth || h > maxTexWidth){ //超出会崩溃
  116. if(w>h){
  117. scaleRatio = maxTexWidth / width
  118. }else{
  119. scaleRatio = maxTexWidth / height
  120. }
  121. }
  122. w = width * scaleRatio
  123. h = height * scaleRatio
  124. this.renderTarget1.setSize( w, h );
  125. this.renderTarget2.setSize( w, h );
  126. for ( var i = 0; i < this.passes.length; i ++ ) {
  127. this.passes[ i ].setSize( w, h );
  128. }
  129. }
  130. } );
  131. export default EffectComposer