Browse Source

Merge pull request #7088 from RaananW/oculus_multiview

Multisampled multiview using the oculus extension
David Catuhe 5 years ago
parent
commit
f6343307c8

+ 3 - 0
dist/preview release/what's new.md

@@ -17,6 +17,7 @@
 - Added support for multiple canvases with one engine [Doc](https://doc.babylonjs.com/how_to/multi_canvases) ([Deltakosh](https://github.com/deltakosh/)
 
 ## Updates
+
 ### General
 
 - Added support for dual shock gamepads ([Deltakosh](https://github.com/deltakosh/))
@@ -141,6 +142,7 @@
 - If canvas does not have WebXR support the scene will still render (mainly Firefox) ([RaananW](https://github.com/RaananW/))
 - Added support for foveated rendering in Oculus Quest ([Deltakosh](https://github.com/deltakosh/))
 - Added option to configure the output canvas ([RaananW](https://github.com/RaananW/))
+- Supporting multisampled multiview rendering using the oculus multiview extension ([RaananW](https://github.com/RaananW/))
 
 ### Ray
 
@@ -213,6 +215,7 @@
 - Prevent an infinite loop when calling `engine.dispose()` in a scene with multiple `SoundTracks` defined ([kirbysayshi](https://github.com/kirbysayshi))
 - Fixed missing properties in serialization / parsing of `coneParticleEmitter` ([Popov72](https://github.com/Popov72))
 - Fix a bug with exit VR and Edge ([RaananW](https://github.com/RaananW/))
+- Fixed an issue with size of texture in multiview ([RaananW](https://github.com/RaananW/))
 
 ## Breaking changes
 

+ 2 - 2
src/Cameras/VR/webVRCamera.ts

@@ -278,7 +278,7 @@ export class WebVRFreeCamera extends FreeCamera implements PoseControlled {
             this.setCameraRigMode(Camera.RIG_MODE_WEBVR, { parentCamera: this, vrDisplay: this._vrDevice, frameData: this._frameData, specs: this._specsVersion });
 
             if (this._attached) {
-                this.getEngine().enableVR();
+                this.getEngine().enableVR(this.webVROptions);
             }
         });
 
@@ -506,7 +506,7 @@ export class WebVRFreeCamera extends FreeCamera implements PoseControlled {
         noPreventDefault = Camera.ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;
 
         if (this._vrDevice) {
-            this.getEngine().enableVR();
+            this.getEngine().enableVR(this.webVROptions);
         }
 
         let hostWindow = this._scene.getEngine().getHostWindow();

+ 9 - 4
src/Engines/Extensions/engine.multiview.ts

@@ -52,13 +52,18 @@ Engine.prototype.createMultiviewRenderTargetTexture = function(width: number, he
 
 Engine.prototype.bindMultiviewFramebuffer = function(multiviewTexture: InternalTexture) {
     var gl: any = this._gl;
-    var ext = this.getCaps().multiview;
+    var ext = this.getCaps().oculusMultiview || this.getCaps().multiview;
 
     this.bindFramebuffer(multiviewTexture, undefined, undefined, undefined, true);
     gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, multiviewTexture._framebuffer);
     if (multiviewTexture._colorTextureArray && multiviewTexture._depthStencilTextureArray) {
-        ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, 0, 2);
-        ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, 0, 2);
+        if (this.getCaps().oculusMultiview) {
+            ext.framebufferTextureMultisampleMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, multiviewTexture.samples, 0, 2);
+            ext.framebufferTextureMultisampleMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, multiviewTexture.samples, 0, 2);
+        } else {
+            ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, 0, 2);
+            ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, 0, 2);
+        }
     } else {
         throw "Invalid multiview frame buffer";
     }
@@ -147,7 +152,7 @@ Scene.prototype._renderMultiviewToSingleView = function(camera: Camera) {
 
     // Render to a multiview texture
     camera._resizeOrCreateMultiviewTexture(
-        (camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.width > 0) ? camera._rigPostProcess.width / 2 : this.getEngine().getRenderWidth(true) / 2,
+        (camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.width > 0) ? camera._rigPostProcess.width : this.getEngine().getRenderWidth(true),
         (camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.height > 0) ? camera._rigPostProcess.height : this.getEngine().getRenderHeight(true)
     );
     if (!this._multiviewSceneUbo) {

+ 5 - 2
src/Engines/Extensions/engine.webVR.ts

@@ -5,6 +5,7 @@ import { Size } from '../../Maths/math.size';
 import { Observable } from '../../Misc/observable';
 import { Tools } from '../../Misc/tools';
 import { DomManagement } from '../../Misc/domManagement';
+import { WebVROptions } from '../../Cameras/VR/webVRCamera';
 
 /**
  * Interface used to define additional presentation attributes
@@ -96,9 +97,10 @@ declare module "../../Engines/engine" {
         /**
          * Call this function to switch to webVR mode
          * Will do nothing if webVR is not supported or if there is no webVR device
+         * @param options the webvr options provided to the camera. mainly used for multiview
          * @see http://doc.babylonjs.com/how_to/webvr_camera
          */
-        enableVR(): void;
+        enableVR(options: WebVROptions): void;
 
         /** @hidden */
         _onVRFullScreenTriggered(): void;
@@ -194,7 +196,7 @@ Engine.prototype._getVRDisplaysAsync = function(): Promise<IDisplayChangedEventA
     });
 };
 
-Engine.prototype.enableVR = function() {
+Engine.prototype.enableVR = function(options: WebVROptions) {
     if (this._vrDisplay && !this._vrDisplay.isPresenting) {
         var onResolved = () => {
             this.onVRRequestPresentComplete.notifyObservers(true);
@@ -209,6 +211,7 @@ Engine.prototype.enableVR = function() {
         var presentationAttributes = {
             highRefreshRate: this.vrPresentationAttributes ? this.vrPresentationAttributes.highRefreshRate : false,
             foveationLevel: this.vrPresentationAttributes ? this.vrPresentationAttributes.foveationLevel : 1,
+            multiview: (this.getCaps().multiview || this.getCaps().oculusMultiview) && options.useMultiview
         };
 
         this._vrDisplay.requestPresent([{

+ 4 - 0
src/Engines/engineCapabilities.ts

@@ -10,6 +10,8 @@ export interface EngineCapabilities {
     maxCombinedTexturesImageUnits: number;
     /** Maximum texture size */
     maxTextureSize: number;
+    /** Maximum texture samples */
+    maxSamples?: number;
     /** Maximum cube texture size */
     maxCubemapTextureSize: number;
     /** Maximum render texture size */
@@ -74,6 +76,8 @@ export interface EngineCapabilities {
     canUseTimestampForTimerQuery: boolean;
     /** Defines if multiview is supported (https://www.khronos.org/registry/webgl/extensions/WEBGL_multiview/) */
     multiview?: any;
+    /** Defines if oculus multiview is supported (https://developer.oculus.com/documentation/oculus-browser/latest/concepts/browser-multiview/) */
+    oculusMultiview?: any;
     /** Function used to let the system compiles shaders in background */
     parallelShaderCompile?: {
         COMPLETION_STATUS_KHR: number;

+ 2 - 0
src/Engines/thinEngine.ts

@@ -705,6 +705,7 @@ export class ThinEngine {
             maxCombinedTexturesImageUnits: this._gl.getParameter(this._gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),
             maxVertexTextureImageUnits: this._gl.getParameter(this._gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS),
             maxTextureSize: this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE),
+            maxSamples: this._gl.getParameter(this._gl.MAX_SAMPLES),
             maxCubemapTextureSize: this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE),
             maxRenderTextureSize: this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE),
             maxVertexAttribs: this._gl.getParameter(this._gl.MAX_VERTEX_ATTRIBS),
@@ -740,6 +741,7 @@ export class ThinEngine {
             textureLOD: (this._webGLVersion > 1 || this._gl.getExtension('EXT_shader_texture_lod')) ? true : false,
             blendMinMax: false,
             multiview: this._gl.getExtension('OVR_multiview2'),
+            oculusMultiview: this._gl.getExtension('OCULUS_multiview'),
             depthTextureExtension: false
         };
 

+ 1 - 0
src/Materials/Textures/MultiviewRenderTarget.ts

@@ -17,6 +17,7 @@ export class MultiviewRenderTarget extends RenderTargetTexture {
         var internalTexture = scene.getEngine().createMultiviewRenderTargetTexture(this.getRenderWidth(), this.getRenderHeight());
         internalTexture.isMultiview = true;
         this._texture = internalTexture;
+        this.samples = this._engine.getCaps().maxSamples || this.samples;
     }
 
     /**