123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /**
- * @author fernandojsg / http://fernandojsg.com
- * @author Takahiro https://github.com/takahirox
- */
- import { WebGLMultiviewRenderTarget } from '../WebGLMultiviewRenderTarget.js';
- import { Matrix3 } from '../../math/Matrix3.js';
- import { Matrix4 } from '../../math/Matrix4.js';
- import { Vector2 } from '../../math/Vector2.js';
- function WebGLMultiview( renderer, requested, options ) {
- options = Object.assign( {}, { debug: false }, options );
- var DEFAULT_NUMVIEWS = 2;
- var gl = renderer.context;
- var capabilities = renderer.capabilities;
- var properties = renderer.properties;
- var maxNumViews = capabilities.maxMultiviewViews;
- var renderTarget, currentRenderTarget;
- var mat3, mat4, cameraArray, renderSize;
- function getMaxViews() {
- return capabilities.maxMultiviewViews;
- }
- function getNumViews() {
- if ( renderTarget && renderer.getRenderTarget() === renderTarget ) {
- return renderTarget.numViews;
- }
- return 0;
- }
- function getCameraArray( camera ) {
- if ( camera.isArrayCamera ) return camera.cameras;
- cameraArray[ 0 ] = camera;
- return cameraArray;
- }
- //
- function isAvailable() {
- return capabilities.multiview;
- }
- function isEnabled() {
- return requested && isAvailable();
- }
- if ( options.debug ) {
- if ( requested && ! isAvailable() ) {
- console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );
- } else if ( requested !== false && isAvailable() ) {
- console.info( 'WebGLRenderer: Multiview enabled' );
- }
- }
- function updateCameraProjectionMatricesUniform( camera, uniforms ) {
- var cameras = getCameraArray( camera );
- for ( var i = 0; i < cameras.length; i ++ ) {
- mat4[ i ].copy( cameras[ i ].projectionMatrix );
- }
- uniforms.setValue( gl, 'projectionMatrices', mat4 );
- }
- function updateCameraViewMatricesUniform( camera, uniforms ) {
- var cameras = getCameraArray( camera );
- for ( var i = 0; i < cameras.length; i ++ ) {
- mat4[ i ].copy( cameras[ i ].matrixWorldInverse );
- }
- uniforms.setValue( gl, 'viewMatrices', mat4 );
- }
- function updateObjectMatricesUniforms( object, camera, uniforms ) {
- var cameras = getCameraArray( camera );
- for ( var i = 0; i < cameras.length; i ++ ) {
- mat4[ i ].multiplyMatrices( cameras[ i ].matrixWorldInverse, object.matrixWorld );
- mat3[ i ].getNormalMatrix( mat4[ i ] );
- }
- uniforms.setValue( gl, 'modelViewMatrices', mat4 );
- uniforms.setValue( gl, 'normalMatrices', mat3 );
- }
- function isMultiviewCompatible( camera ) {
- if ( ! camera.isArrayCamera ) return true;
- var cameras = camera.cameras;
- if ( cameras.length > maxNumViews ) return false;
- for ( var i = 1, il = cameras.length; i < il; i ++ ) {
- if ( cameras[ 0 ].viewport.z !== cameras[ i ].viewport.z ||
- cameras[ 0 ].viewport.w !== cameras[ i ].viewport.w ) return false;
- }
- return true;
- }
- function resizeRenderTarget( camera ) {
- if ( currentRenderTarget ) {
- renderSize.set( currentRenderTarget.width, currentRenderTarget.height );
- } else {
- renderer.getDrawingBufferSize( renderSize );
- }
- if ( camera.isArrayCamera ) {
- var viewport = camera.cameras[ 0 ].viewport;
- renderTarget.setSize( viewport.z, viewport.w );
- renderTarget.setNumViews( camera.cameras.length );
- } else {
- renderTarget.setSize( renderSize.x, renderSize.y );
- renderTarget.setNumViews( DEFAULT_NUMVIEWS );
- }
- }
- function attachRenderTarget( camera ) {
- if ( ! isMultiviewCompatible( camera ) ) return;
- currentRenderTarget = renderer.getRenderTarget();
- resizeRenderTarget( camera );
- renderer.setRenderTarget( renderTarget );
- }
- function detachRenderTarget( camera ) {
- if ( renderTarget !== renderer.getRenderTarget() ) return false;
- renderer.setRenderTarget( currentRenderTarget );
- flush( camera );
- }
- function flush( camera ) {
- var srcRenderTarget = renderTarget;
- var numViews = srcRenderTarget.numViews;
- var srcFramebuffers = properties.get( srcRenderTarget ).__webglViewFramebuffers;
- var viewWidth = srcRenderTarget.width;
- var viewHeight = srcRenderTarget.height;
- if ( camera.isArrayCamera ) {
- for ( var i = 0; i < numViews; i ++ ) {
- var viewport = camera.cameras[ i ].viewport;
- var x1 = viewport.x;
- var y1 = viewport.y;
- var x2 = x1 + viewport.z;
- var y2 = y1 + viewport.w;
- gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ i ] );
- gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, x1, y1, x2, y2, gl.COLOR_BUFFER_BIT, gl.NEAREST );
- }
- } else {
- gl.bindFramebuffer( gl.READ_FRAMEBUFFER, srcFramebuffers[ 0 ] );
- gl.blitFramebuffer( 0, 0, viewWidth, viewHeight, 0, 0, renderSize.x, renderSize.y, gl.COLOR_BUFFER_BIT, gl.NEAREST );
- }
- }
- if ( isEnabled() ) {
- renderTarget = new WebGLMultiviewRenderTarget( 0, 0, DEFAULT_NUMVIEWS );
- renderSize = new Vector2();
- mat4 = [];
- mat3 = [];
- cameraArray = [];
- for ( var i = 0; i < getMaxViews(); i ++ ) {
- mat4[ i ] = new Matrix4();
- mat3[ i ] = new Matrix3();
- }
- }
- this.attachRenderTarget = attachRenderTarget;
- this.detachRenderTarget = detachRenderTarget;
- this.isAvailable = isAvailable;
- this.isEnabled = isEnabled;
- this.getNumViews = getNumViews;
- this.updateCameraProjectionMatricesUniform = updateCameraProjectionMatricesUniform;
- this.updateCameraViewMatricesUniform = updateCameraViewMatricesUniform;
- this.updateObjectMatricesUniforms = updateObjectMatricesUniforms;
- }
- export { WebGLMultiview };
|