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

Added arrayCamera support on multiview

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