提交 ea60c3b7 编写于 作者: F Fernando Serrano

WebGLMultiviewRenderTarget added and refactored WebGLMultiview

上级 96d2a4d7
/**
* @author fernandojsg / http://fernandojsg.com
* @author Takahiro https://github.com/takahirox
*/
import { WebGLRenderTarget } from './WebGLRenderTarget.js';
function WebGLMultiviewRenderTarget( width, height, numViews, options ) {
WebGLRenderTarget.call( this, width, height, options );
this.depthBuffer = false;
this.stencilBuffer = false;
this.numViews = numViews;
}
WebGLMultiviewRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), {
constructor: WebGLMultiviewRenderTarget,
isWebGLMultiviewRenderTarget: true,
copy: function ( source ) {
WebGLRenderTarget.prototype.copy.call( this, source );
this.numViews = source.numViews;
return this;
}
} );
export { WebGLMultiviewRenderTarget };
......@@ -315,7 +315,9 @@ function WebGLRenderer( parameters ) {
this.vr = vr;
var multiview = this.multiview = new WebGLMultiview( _multiviewRequested, _gl, _canvas, extensions, capabilities, properties );
var multiview = new WebGLMultiview( _this, _multiviewRequested );
this.multiview = multiview;
// shadow map
......@@ -1178,13 +1180,13 @@ function WebGLRenderer( parameters ) {
this.setRenderTarget( renderTarget );
} else if ( this.multiview.isEnabled() ) {
}
this.setRenderTarget( this.multiview.renderTarget );
this.multiview.bindFramebuffer( camera );
if ( multiview.isEnabled() ) {
}
multiview.attachRenderTarget( camera );
}
//
......@@ -1230,12 +1232,6 @@ function WebGLRenderer( parameters ) {
textures.updateMultisampleRenderTarget( _currentRenderTarget );
if ( this.multiview.isEnabled() ) {
this.multiview.unbindFramebuffer( camera );
}
}
// Ensure depth buffer writing is enabled so it can be cleared on next render
......@@ -1246,6 +1242,12 @@ function WebGLRenderer( parameters ) {
state.setPolygonOffset( false );
if ( this.multiview.isEnabled() ) {
this.multiview.detachRenderTarget( camera );
}
if ( vr.enabled ) {
vr.submitFrame();
......
/**
* @author fernandojsg / http://fernandojsg.com
* @author Takahiro https://github.com/takahirox
*/
import { WebGLRenderTarget } from '../WebGLRenderTarget.js';
import { WebGLMultiviewRenderTarget } from '../WebGLMultiviewRenderTarget.js';
import { Matrix3 } from '../../math/Matrix3.js';
import { Matrix4 } from '../../math/Matrix4.js';
function WebGLMultiview( requested, gl, canvas, extensions, capabilities, properties ) {
function WebGLMultiview( renderer, requested ) {
var gl = renderer.context;
var canvas = renderer.domElement;
var capabilities = renderer.capabilities;
var properties = renderer.properties;
this.isAvailable = function () {
......@@ -43,15 +49,7 @@ function WebGLMultiview( requested, gl, canvas, extensions, capabilities, proper
}
var numViews = 2;
var framebuffer; // multiview framebuffer.
var viewFramebuffer; // single views inside the multiview framebuffer.
var framebufferWidth = 0;
var framebufferHeight = 0;
var texture = {
color: null,
depthStencil: null
};
var renderTarget, currentRenderTarget;
this.computeCameraMatrices = function ( camera ) {
......@@ -133,51 +131,11 @@ function WebGLMultiview( requested, gl, canvas, extensions, capabilities, proper
};
// @todo Get ArrayCamera
this.createMultiviewRenderTargetTexture = function () {
var halfWidth = Math.floor( canvas.width * 0.5 );
framebuffer = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );
var ext = extensions.get( 'OVR_multiview2' );
texture.color = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, halfWidth, canvas.height, numViews, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, 0, numViews );
texture.depthStencil = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.depthStencil );
gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.DEPTH24_STENCIL8, halfWidth, canvas.height, numViews, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null );
ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, texture.depthStencil, 0, 0, numViews );
viewFramebuffer = new Array( numViews );
for ( var viewIndex = 0; viewIndex < numViews; ++ viewIndex ) {
viewFramebuffer[ viewIndex ] = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, viewFramebuffer[ viewIndex ] );
gl.framebufferTextureLayer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, viewIndex );
}
framebufferWidth = halfWidth;
framebufferHeight = canvas.height;
this.renderTarget = new WebGLRenderTarget( framebufferWidth, framebufferHeight );
// @hack This should be done in WebGLTextures?
properties.get( this.renderTarget ).__webglFramebuffer = framebuffer;
this.attachRenderTarget = function ( camera ) {
};
this.bindFramebuffer = function ( camera ) {
currentRenderTarget = renderer.getRenderTarget();
// Resize if needed
var width = canvas.width;
var height = canvas.height;
......@@ -191,27 +149,18 @@ function WebGLMultiview( requested, gl, canvas, extensions, capabilities, proper
}
if ( framebufferWidth < width || framebufferHeight < height ) {
console.log( 'WebGLMultiview: Updating multiview FBO with dimensions: ', width, height );
gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, width, height, numViews, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.depthStencil );
gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.DEPTH24_STENCIL8, width, height, numViews, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null );
framebufferWidth = width;
framebufferHeight = height;
renderTarget.setSize( width, height );
this.renderTarget.setSize( width, height );
}
gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, framebuffer );
renderer.setRenderTarget( renderTarget );
};
this.unbindFramebuffer = function ( camera ) {
this.detachRenderTarget = function ( camera ) {
gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );
var viewFramebuffers = properties.get( renderTarget ).__webglViewFramebuffers;
// @todo Use actual framebuffer
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
if ( camera.isArrayCamera ) {
......@@ -224,24 +173,27 @@ function WebGLMultiview( requested, gl, canvas, extensions, capabilities, proper
var width = bounds.z * canvas.width;
var height = bounds.w * canvas.height;
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffer[ i ] );
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffers[ i ] );
gl.blitFramebuffer( 0, 0, width, height, x, y, x + width, y + height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
}
} else {
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffer[ 0 ] );
// If no array camera, blit just one view
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffers[ 0 ] );
gl.blitFramebuffer( 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
}
renderer.setRenderTarget( currentRenderTarget );
};
if ( this.isEnabled() ) {
this.createMultiviewRenderTargetTexture();
renderTarget = new WebGLMultiviewRenderTarget( canvas.width, canvas.height, numViews );
}
......
......@@ -944,6 +944,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
var isMultiview = ( renderTarget.isWebGLMultiviewRenderTarget === true );
var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2;
// Setup framebuffer
......@@ -996,6 +997,54 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
}
} else if ( isMultiview ) {
if ( capabilities.multiview ) {
var width = renderTarget.width;
var height = renderTarget.height;
var numViews = renderTarget.numViews;
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
var ext = extensions.get( 'OVR_multiview2' );
var colorTexture = _gl.createTexture();
_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, colorTexture );
_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
_gl.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, _gl.RGBA8, width, height, numViews, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
ext.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, colorTexture, 0, 0, numViews );
var depthStencilTexture = _gl.createTexture();
_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, depthStencilTexture );
_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
_gl.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, _gl.DEPTH24_STENCIL8, width, height, numViews, 0, _gl.DEPTH_STENCIL, _gl.UNSIGNED_INT_24_8, null );
ext.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0, 0, numViews );
var viewFramebuffers = new Array( numViews );
for ( var viewIndex = 0; viewIndex < numViews; ++ viewIndex ) {
viewFramebuffers[ viewIndex ] = _gl.createFramebuffer();
_gl.bindFramebuffer( _gl.FRAMEBUFFER, viewFramebuffers[ viewIndex ] );
_gl.framebufferTextureLayer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, colorTexture, 0, viewIndex );
}
renderTargetProperties.__webglColorTexture = colorTexture;
renderTargetProperties.__webglDepthStencilTexture = depthStencilTexture;
renderTargetProperties.__webglViewFramebuffers = viewFramebuffers;
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, null );
}
} else {
console.warn( 'THREE.WebGLRenderer: WebGLMultiviewRenderTarget can only be used with WebGL2 and Multiview extension support.' );
}
}
......@@ -1021,7 +1070,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
} else {
} else if ( ! isMultiview ) {
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, supportsMips );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册