WebGLMultiview.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. function WebGLMultiview( renderer, requested, options ) {
  9. options = Object.assign( {}, { debug: false }, options );
  10. var gl = renderer.context;
  11. var canvas = renderer.domElement;
  12. var capabilities = renderer.capabilities;
  13. var properties = renderer.properties;
  14. var numViews = 2;
  15. var renderTarget, currentRenderTarget;
  16. // Auxiliary matrices to be used when updating arrays of uniforms
  17. var aux = {
  18. mat4: [],
  19. mat3: []
  20. };
  21. for ( var i = 0; i < numViews; i ++ ) {
  22. aux.mat4[ i ] = new Matrix4();
  23. aux.mat3[ i ] = new Matrix3();
  24. }
  25. //
  26. this.isAvailable = function () {
  27. return capabilities.multiview;
  28. };
  29. this.getNumViews = function () {
  30. return numViews;
  31. };
  32. this.getMaxViews = function () {
  33. return capabilities.maxMultiviewViews;
  34. };
  35. this.isEnabled = function () {
  36. return requested && this.isAvailable();
  37. };
  38. if ( options.debug ) {
  39. if ( requested && ! this.isAvailable() ) {
  40. console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );
  41. } else if ( requested !== false && this.isAvailable() ) {
  42. console.info( 'WebGLRenderer: Multiview enabled' );
  43. }
  44. }
  45. this.updateCameraProjectionMatrices = function ( camera, p_uniforms ) {
  46. if ( camera.isArrayCamera ) {
  47. for ( var i = 0; i < numViews; i ++ ) {
  48. aux.mat4[ i ].copy( camera.cameras[ i ].projectionMatrix );
  49. }
  50. } else {
  51. for ( var i = 0; i < numViews; i ++ ) {
  52. aux.mat4[ i ].copy( camera.projectionMatrix );
  53. }
  54. }
  55. p_uniforms.setValue( gl, 'projectionMatrices', aux.mat4 );
  56. };
  57. this.updateCameraViewMatrices = function ( camera, p_uniforms ) {
  58. if ( camera.isArrayCamera ) {
  59. for ( var i = 0; i < numViews; i ++ ) {
  60. aux.mat4[ i ].copy( camera.cameras[ i ].matrixWorldInverse );
  61. }
  62. } else {
  63. for ( var i = 0; i < numViews; i ++ ) {
  64. aux.mat4[ i ].copy( camera.matrixWorldInverse );
  65. }
  66. }
  67. p_uniforms.setValue( gl, 'viewMatrices', aux.mat4 );
  68. };
  69. this.updateObjectMatrices = function ( object, camera, p_uniforms ) {
  70. if ( camera.isArrayCamera ) {
  71. for ( var i = 0; i < numViews; i ++ ) {
  72. aux.mat4[ i ].multiplyMatrices( camera.cameras[ i ].matrixWorldInverse, object.matrixWorld );
  73. aux.mat3[ i ].getNormalMatrix( aux.mat4[ i ] );
  74. }
  75. } else {
  76. // In this case we still need to provide an array of matrices but just the first one will be used
  77. aux.mat4[ 0 ].multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
  78. aux.mat3[ 0 ].getNormalMatrix( aux.mat4[ 0 ] );
  79. for ( var i = 1; i < numViews; i ++ ) {
  80. aux.mat4[ i ].copy( aux.mat4[ 0 ] );
  81. aux.mat3[ i ].copy( aux.mat3[ 0 ] );
  82. }
  83. }
  84. p_uniforms.setValue( gl, 'modelViewMatrices', aux.mat4 );
  85. p_uniforms.setValue( gl, 'normalMatrices', aux.mat3 );
  86. };
  87. this.attachRenderTarget = function ( camera ) {
  88. currentRenderTarget = renderer.getRenderTarget();
  89. // Resize if needed
  90. var width = canvas.width;
  91. var height = canvas.height;
  92. if ( camera.isArrayCamera ) {
  93. // Every camera must have the same size, so we just get the size from the first one
  94. var bounds = camera.cameras[ 0 ].bounds;
  95. width *= bounds.z;
  96. height *= bounds.w;
  97. }
  98. renderTarget.setSize( width, height );
  99. renderer.setRenderTarget( renderTarget );
  100. };
  101. this.detachRenderTarget = function ( camera ) {
  102. var viewFramebuffers = properties.get( renderTarget ).__webglViewFramebuffers;
  103. // @todo Use actual framebuffer
  104. gl.bindFramebuffer( gl.FRAMEBUFFER, null );
  105. if ( camera.isArrayCamera ) {
  106. for ( var i = 0; i < camera.cameras.length; i ++ ) {
  107. var bounds = camera.cameras[ i ].bounds;
  108. var x = bounds.x * canvas.width;
  109. var y = bounds.y * canvas.height;
  110. var width = bounds.z * canvas.width;
  111. var height = bounds.w * canvas.height;
  112. gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffers[ i ] );
  113. gl.blitFramebuffer( 0, 0, width, height, x, y, x + width, y + height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
  114. }
  115. } else {
  116. // If no array camera, blit just one view
  117. gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffers[ 0 ] );
  118. gl.blitFramebuffer( 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
  119. }
  120. renderer.setRenderTarget( currentRenderTarget );
  121. };
  122. if ( this.isEnabled() ) {
  123. renderTarget = new WebGLMultiviewRenderTarget( canvas.width, canvas.height, numViews );
  124. }
  125. }
  126. export { WebGLMultiview };
粤ICP备19079148号