Browse Source

Added arrayCamera support on multiview

Fernando Serrano 6 years ago
parent
commit
45ed105d58

+ 19 - 25
src/renderers/WebGLRenderer.js

@@ -318,19 +318,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
 
@@ -1380,22 +1369,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 );
 
@@ -1412,7 +1406,7 @@ function WebGLRenderer( parameters ) {
 
 			}
 
-			multiviewObject.unbindMultiviewFrameBuffer();
+			multiviewObject.unbindMultiviewFrameBuffer( camera );
 
 		} else {
 
@@ -1753,7 +1747,7 @@ function WebGLRenderer( parameters ) {
 
 		if ( refreshProgram || _currentCamera !== camera ) {
 
-			if ( vr.multiview ) {
+			if ( multiviewEnabled ) {
 
 				if ( false && vr.isPresenting() ) {
 
@@ -1818,7 +1812,7 @@ function WebGLRenderer( parameters ) {
 				material.isShaderMaterial ||
 				material.skinning ) {
 
-				if ( vr.multiview ) {
+				if ( multiviewEnabled ) {
 
 					if ( vr.isPresenting() ) {
 

+ 6 - 8
src/renderers/webgl/WebGLCapabilities.js

@@ -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
 
 	};
 

+ 85 - 46
src/renderers/webgl/WebGLMultiview.js

@@ -1,38 +1,45 @@
+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();
+
+  }
 
 }
 

+ 4 - 4
src/renderers/webgl/WebGLProgram.js

@@ -413,7 +413,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;',
@@ -542,7 +542,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]'
@@ -603,7 +603,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;',
@@ -618,7 +618,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'