提交 9072316c 编写于 作者: F Fernando Serrano

Added arrayCamera support on multiview

上级 3277fefb
......@@ -315,19 +315,8 @@ function WebGLRenderer( parameters ) {
this.vr = vr;
if ( _multiview && ! capabilities.multiview ) {
console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );
this.vr.multiview = false;
} else if ( _multiview !== false && capabilities.multiview ) {
console.info( 'WebGLRenderer: Multiview enabled' );
this.vr.multiview = true;
}
var multiviewObject = new WebGLMultiview(_multiview, _gl, _canvas, extensions, capabilities );
var multiviewEnabled = this.multiviewEnabled = multiviewObject.isEnabled();
// shadow map
......@@ -1377,22 +1366,27 @@ function WebGLRenderer( parameters ) {
}
var multiviewObject = new WebGLMultiview(_gl, _canvas, extensions );
function renderObjects( renderList, scene, camera, overrideMaterial ) {
if ( vr.multiview ) {
multiviewObject.bindMultiviewFrameBuffer();
if ( multiviewEnabled ) {
multiviewObject.bindMultiviewFrameBuffer( camera );
_gl.disable( _gl.SCISSOR_TEST );
var width = _canvas.width;
var height = _canvas.height;
if ( camera.isArrayCamera ) {
var height = _canvas.height;
var width = Math.floor( _canvas.width * 0.5 );
var halfWidth = Math.floor(width * 0.5);
} else {
var width = _canvas.width;
var height = _canvas.height;
_gl.viewport( 0, 0, halfWidth, height );
renderer.setViewport( 0, 0, halfWidth, height );
}
_gl.viewport( 0, 0, width, height );
renderer.setViewport( 0, 0, width, height );
_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
......@@ -1409,7 +1403,7 @@ function WebGLRenderer( parameters ) {
}
multiviewObject.unbindMultiviewFrameBuffer();
multiviewObject.unbindMultiviewFrameBuffer( camera );
} else {
......@@ -1750,7 +1744,7 @@ function WebGLRenderer( parameters ) {
if ( refreshProgram || _currentCamera !== camera ) {
if ( vr.multiview ) {
if ( multiviewEnabled ) {
if ( false && vr.isPresenting() ) {
......@@ -1815,7 +1809,7 @@ function WebGLRenderer( parameters ) {
material.isShaderMaterial ||
material.skinning ) {
if ( vr.multiview ) {
if ( multiviewEnabled ) {
if ( vr.isPresenting() ) {
......
......@@ -86,13 +86,10 @@ function WebGLCapabilities( gl, extensions, parameters ) {
var maxSamples = isWebGL2 ? gl.getParameter( gl.MAX_SAMPLES ) : 0;
var multiview = isWebGL2 && ( !! extensions.get( 'WEBGL_multiview' ) || !! extensions.get( 'OVR_multiview' ) || !! extensions.get( 'OVR_multiview2' ) );
/*
var ovrMultiview2 = extensions.get( 'OVR_multiview2' );
if (ovrMultiview2) {
var num = gl.getParameter(ovrMultiview2.MAX_VIEWS_OVR);
}
*/
var multiviewExt = extensions.get( 'OVR_multiview2' );
var multiview = isWebGL2 && ( !! multiviewExt );
var maxMultiviewViews = multiview ? gl.getParameter(multiviewExt.MAX_VIEWS_OVR) : 1;
return {
isWebGL2: isWebGL2,
......@@ -119,7 +116,8 @@ function WebGLCapabilities( gl, extensions, parameters ) {
maxSamples: maxSamples,
multiview: multiview
multiview: multiview,
maxMultiviewViews: maxMultiviewViews
};
......
function WebGLMultiview( requested, gl, canvas, extensions, capabilities ) {
function err() {
this.isAvailable = function () {
console.error( bgl.getError() );
return capabilities.multiview;
}
}
var bgl;
this.getMaxViews = function () {
function WebGLMultiview( gl, canvas, extensions ) {
return capabilities.maxMultiviewViews;
var NUM_MULTIVIEW_VIEWS = 2;
bgl = gl;
var width = canvas.width;
var height = canvas.height;
var g_multiviewFb; // multiview framebuffer.
var g_multiviewViewFb; // single views inside the multiview framebuffer.
var g_multiviewColorTexture; // Color texture for multiview framebuffer.
var g_multiviewDepth; // Depth texture for multiview framebuffer.
var g_multiviewFbWidth = 0;
var g_multiviewFbHeight = 0;
}
this.isEnabled = function () {
return requested && this.isAvailable();
var ext = extensions.get( 'OVR_multiview2' );
if (!ext) {
return;
}
if ( requested && ! this.isAvailable() ) {
console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );
} else if ( requested !== false && this.isAvailable() ) {
console.info( 'WebGLRenderer: Multiview enabled' );
}
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 framebuffer = gl.createFramebuffer();
var multiviewViewFb = null;
this.createMultiviewRenderTargetTexture = function () {
......@@ -41,62 +48,94 @@ function WebGLMultiview( gl, canvas, extensions ) {
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, NUM_MULTIVIEW_VIEWS, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, 0, NUM_MULTIVIEW_VIEWS );
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, NUM_MULTIVIEW_VIEWS, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null );
ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, texture.depthStencil, 0, 0, NUM_MULTIVIEW_VIEWS );
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 );
multiviewViewFb = [ null, null ];
for ( var viewIndex = 0; viewIndex < 2; ++ viewIndex ) {
viewFramebuffer = new Array( numViews );
for ( var viewIndex = 0; viewIndex < numViews; ++ viewIndex ) {
multiviewViewFb[ viewIndex ] = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, multiviewViewFb[ viewIndex ] );
viewFramebuffer[ viewIndex ] = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, viewFramebuffer[ viewIndex ] );
gl.framebufferTextureLayer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, viewIndex );
}
g_multiviewFbWidth = halfWidth;
g_multiviewFbHeight = canvas.height;
framebufferWidth = halfWidth;
framebufferHeight = canvas.height;
};
this.bindMultiviewFrameBuffer = function () {
this.bindMultiviewFrameBuffer = function ( camera ) {
var halfWidth = Math.floor( canvas.width * 0.5 );
if ( g_multiviewFbWidth < halfWidth || g_multiviewFbHeight < canvas.height ) {
console.log( 'Updating multiview FBO with dimensions: ', halfWidth, canvas.height );
if (camera.isArrayCamera) {
} else {
halfWidth *= 2;
}
if ( framebufferWidth < halfWidth || framebufferHeight < canvas.height ) {
console.log( 'WebGLMultiview: Updating multiview FBO with dimensions: ', halfWidth, canvas.height );
gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, halfWidth, canvas.height, NUM_MULTIVIEW_VIEWS, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, halfWidth, canvas.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, halfWidth, canvas.height, NUM_MULTIVIEW_VIEWS, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
g_multiviewFbWidth = halfWidth;
g_multiviewFbHeight = canvas.height;
gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.DEPTH24_STENCIL8, halfWidth, canvas.height, numViews, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
framebufferWidth = halfWidth;
framebufferHeight = canvas.height;
}
// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, framebuffer );
};
this.unbindMultiviewFrameBuffer = function () {
this.unbindMultiviewFrameBuffer = function ( camera ) {
var halfWidth = Math.floor( canvas.width * 0.5 );
gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, multiviewViewFb[ 0 ] );
gl.blitFramebuffer( 0, 0, halfWidth, canvas.height, 0, 0, halfWidth, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, multiviewViewFb[ 1 ] );
gl.blitFramebuffer( 0, 0, halfWidth, canvas.height, halfWidth, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );
if ( camera.isArrayCamera ) {
for ( var i = 0; i < camera.cameras.length; i ++ ) {
var bounds = camera.cameras[ i ].bounds;
var x = bounds.x * canvas.width;
var y = bounds.y * canvas.height;
var width = bounds.z * canvas.width;
var height = bounds.w * canvas.height;
gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffer[ 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 ] );
gl.blitFramebuffer( 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
}
};
this.createMultiviewRenderTargetTexture();
if ( this.isEnabled() ) {
this.createMultiviewRenderTargetTexture();
}
}
......
......@@ -430,7 +430,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
'uniform mat4 modelMatrix;',
'uniform vec3 cameraPosition;',
renderer.vr.multiview ? [
renderer.multiviewEnabled ? [
'uniform mat4 modelViewMatrix;',
'uniform mat4 projectionMatrices[2];',
'uniform mat3 normalMatrix;',
......@@ -566,7 +566,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
'uniform vec3 cameraPosition;',
renderer.vr.multiview ? [
renderer.multiviewEnabled ? [
'uniform mat4 viewMatrices[2];',
'#define viewMatrix viewMatrices[VIEW_ID]'
......@@ -627,7 +627,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
prefixVertex = [
'#version 300 es\n',
renderer.vr.multiview ? [
renderer.multiviewEnabled ? [
'#extension GL_OVR_multiview2 : require',
'layout(num_views = 2) in;',
......@@ -642,7 +642,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
prefixFragment = [
'#version 300 es\n',
renderer.vr.multiview ? [
renderer.multiviewEnabled ? [
'#extension GL_OVR_multiview2 : require',
'#define VIEW_ID gl_ViewID_OVR'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册