WebGLMultiview.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /**
  2. * @author fernandojsg / http://fernandojsg.com
  3. * @author Takahiro https://github.com/takahirox
  4. */
  5. import { WebGLMultiviewRenderTarget } from '../WebGLMultiviewRenderTarget.js';
  6. import { Matrix3 } from '../../math/Matrix3.js';
  7. import { Matrix4 } from '../../math/Matrix4.js';
  8. import { Vector2 } from '../../math/Vector2.js';
  9. function WebGLMultiview( renderer, requested, options ) {
  10. options = Object.assign( {}, { debug: false }, options );
  11. var DEFAULT_NUMVIEWS = 2;
  12. var gl = renderer.context;
  13. var capabilities = renderer.capabilities;
  14. var properties = renderer.properties;
  15. var renderTarget, currentRenderTarget;
  16. var mat3, mat4, cameraArray, renderSize;
  17. function getMaxViews() {
  18. return capabilities.maxMultiviewViews;
  19. }
  20. function getNumViews() {
  21. if ( renderTarget && renderer.getRenderTarget() === renderTarget ) {
  22. return renderTarget.numViews;
  23. }
  24. return 0;
  25. }
  26. function getCameraArray( camera ) {
  27. if ( camera.isArrayCamera ) return camera.cameras;
  28. cameraArray[ 0 ] = camera;
  29. return cameraArray;
  30. }
  31. //
  32. function isAvailable() {
  33. return capabilities.multiview;
  34. }
  35. function isEnabled() {
  36. return requested && isAvailable();
  37. }
  38. if ( options.debug ) {
  39. if ( requested && ! isAvailable() ) {
  40. console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );
  41. } else if ( requested !== false && isAvailable() ) {
  42. console.info( 'WebGLRenderer: Multiview enabled' );
  43. }
  44. }
  45. function updateCameraProjectionMatricesUniform( camera, uniforms ) {
  46. var cameras = getCameraArray( camera );
  47. for ( var i = 0; i < cameras.length; i ++ ) {
  48. mat4[ i ].copy( cameras[ i ].projectionMatrix );
  49. }
  50. uniforms.setValue( gl, 'projectionMatrices', mat4 );
  51. }
  52. function updateCameraViewMatricesUniform( camera, uniforms ) {
  53. var cameras = getCameraArray( camera );
  54. for ( var i = 0; i < cameras.length; i ++ ) {
  55. mat4[ i ].copy( cameras[ i ].matrixWorldInverse );
  56. }
  57. uniforms.setValue( gl, 'viewMatrices', mat4 );
  58. }
  59. function updateObjectMatricesUniforms( object, camera, uniforms ) {
  60. var cameras = getCameraArray( camera );
  61. for ( var i = 0; i < cameras.length; i ++ ) {
  62. mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
  63. mat3[ i ].getNormalMatrix( mat4[ i ] );
  64. }
  65. uniforms.setValue( gl, 'modelViewMatrices', mat4 );
  66. uniforms.setValue( gl, 'normalMatrices', mat3 );
  67. }
  68. function resizeRenderTarget( camera ) {
  69. if ( currentRenderTarget ) {
  70. renderSize.set( currentRenderTarget.width, currentRenderTarget.height );
  71. } else {
  72. renderer.getDrawingBufferSize( renderSize );
  73. }
  74. if ( camera.isArrayCamera ) {
  75. var bounds = camera.cameras[ 0 ].bounds;
  76. renderTarget.setSize( bounds.z * renderSize.x, bounds.w * renderSize.y );
  77. renderTarget.setNumViews( camera.cameras.length );
  78. } else {
  79. renderTarget.setSize( renderSize.x, renderSize.y );
  80. renderTarget.setNumViews( DEFAULT_NUMVIEWS );
  81. }
  82. }
  83. function attachRenderTarget( camera ) {
  84. currentRenderTarget = renderer.getRenderTarget();
  85. resizeRenderTarget( camera );
  86. renderer.setRenderTarget( renderTarget );
  87. }
  88. function detachRenderTarget( camera ) {
  89. renderer.setRenderTarget( currentRenderTarget );
  90. flush( camera );
  91. }
  92. function flush( camera ) {
  93. var srcRenderTarget = renderTarget;
  94. var numViews = srcRenderTarget.numViews;
  95. var srcFramebuffers = properties.get( srcRenderTarget ).__webglViewFramebuffers;
  96. var viewWidth = srcRenderTarget.width;
  97. var viewHeight = srcRenderTarget.height;
  98. if ( camera.isArrayCamera ) {
  99. for ( var i = 0; i < numViews; i ++ ) {
  100. var bounds = camera.cameras[ i ].bounds;
  101. var x1 = bounds.x * renderSize.x;
  102. var y1 = bounds.y * renderSize.y;
  103. var x2 = x1 + bounds.z * renderSize.x;
  104. var y2 = y1 + bounds.w * renderSize.y;
  105. gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ i ] );
  106. gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, x1, y1, x2, y2, gl.COLOR_BUFFER_BIT, gl.NEAREST );
  107. }
  108. } else {
  109. gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ 0 ] );
  110. gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, 0, 0, renderSize.x, renderSize.y, gl.COLOR_BUFFER_BIT, gl.NEAREST );
  111. }
  112. }
  113. if ( isEnabled() ) {
  114. renderTarget = new WebGLMultiviewRenderTarget( 0, 0, DEFAULT_NUMVIEWS );
  115. renderSize = new Vector2();
  116. mat4 = [];
  117. mat3 = [];
  118. cameraArray = [];
  119. for ( var i = 0; i < getMaxViews(); i ++ ) {
  120. mat4[ i ] = new Matrix4();
  121. mat3[ i ] = new Matrix3();
  122. }
  123. }
  124. this.attachRenderTarget = attachRenderTarget;
  125. this.detachRenderTarget = detachRenderTarget;
  126. this.isAvailable = isAvailable;
  127. this.isEnabled = isEnabled;
  128. this.getNumViews = getNumViews;
  129. this.updateCameraProjectionMatricesUniform = updateCameraProjectionMatricesUniform;
  130. this.updateCameraViewMatricesUniform = updateCameraViewMatricesUniform;
  131. this.updateObjectMatricesUniforms = updateObjectMatricesUniforms;
  132. }
  133. export { WebGLMultiview };
粤ICP备19079148号