Parcourir la source

move gl logic to engine

Trevor Baron il y a 6 ans
Parent
commit
f3e3a7dcee

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

@@ -28,6 +28,7 @@
 - Added clear coat support to PBR ([Sebavan](https://github.com/Sebavan)) **** NEED DEMO or DOC LINK)
 - Added anisotropy support to PBR ([Sebavan](https://github.com/Sebavan)) **** NEED DEMO or DOC LINK)
 - Added `TrailMesh` class. Credit to furcatomasz ([danjpar](https://github.com/danjpar)) **** NEED DEMO or DOC LINK)
+- Support rendering to a Multiview outputRenderTargetTexture to improve performance for XR scenarios ([TrevorDev](https://github.com/TrevorDev))
 
 ## Updates
 
@@ -103,8 +104,7 @@
 - Inspector light gizmo ([TrevorDev](https://github.com/TrevorDev))
 - Added option `multiMultiMaterials` to mesh.mergeMeshes ([danjpar](https://github.com/danjpar))
 - Expose fallback camera distortion metrics option in vrExperienceHelper ([TrevorDev](https://github.com/TrevorDev))
-- Add setColor method to boundingBoxGizmo ([TrevorDev](https://github.com/TrevorDev))
-- Support rendering to a Multiview outputRenderTargetTexture to improve performance for XR scenarios ([TrevorDev](https://github.com/TrevorDev))
+- Add setColor method to boundingBoxGizmo ([TrevorDev](https://github.com/TrevorDev)
 
 ### OBJ Loader
 - Add color vertex support (not part of standard) ([brianzinn](https://github.com/brianzinn))

+ 42 - 0
src/Engines/engine.ts

@@ -5549,6 +5549,48 @@ export class Engine {
     }
 
     /**
+     * Creates a new multiview render target
+     * @param width defines the width of the texture
+     * @param height defines the height of the texture
+     */
+    public createMultiviewRenderTargetTexture(width:number, height:number){
+        var gl = this._gl;
+        
+        if (!this.getCaps().multiview) {
+            throw "Multiview is not supported";
+        }
+
+        var internalTexture = new InternalTexture(this, InternalTexture.DATASOURCE_UNKNOWN, true);
+        internalTexture.width = width;
+        internalTexture.height = height;
+        internalTexture._framebuffer = gl.createFramebuffer();
+
+        internalTexture._colorTextureArray = gl.createTexture();
+        gl.bindTexture(gl.TEXTURE_2D_ARRAY, internalTexture._colorTextureArray);
+        (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, 2);
+
+        internalTexture._depthStencilTextureArray = gl.createTexture();
+        gl.bindTexture(gl.TEXTURE_2D_ARRAY, internalTexture._depthStencilTextureArray);
+        (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, (gl as any).DEPTH32F_STENCIL8, width, height, 2);
+
+        return internalTexture;
+    }
+
+    public bindMultiviewFramebuffer(multiviewTexture: InternalTexture){
+        var gl: any = this._gl;
+        var ext = this.getCaps().multiview;
+
+        this.bindFramebuffer(multiviewTexture, undefined, undefined, undefined, true);
+        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, multiviewTexture._framebuffer);
+        if(multiviewTexture._colorTextureArray && multiviewTexture._depthStencilTextureArray){
+            ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, 0, 2);
+            ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, 0, 2);
+        }else{
+            throw "Invalid multiview frame buffer";
+        }
+    }
+
+    /**
      * Creates a new render target cube texture
      * @param size defines the size of the texture
      * @param options defines the options used to create the texture

+ 6 - 0
src/Materials/Textures/internalTexture.ts

@@ -217,6 +217,12 @@ export class InternalTexture implements IInternalTextureTracker {
     /** @hidden */
     public _lodGenerationOffset: number = 0;
 
+    // Multiview
+    /** @hidden */
+    public _colorTextureArray: Nullable<WebGLTexture>;
+    /** @hidden */
+    public _depthStencilTextureArray:  Nullable<WebGLTexture>;
+
     // The following three fields helps sharing generated fixed LODs for texture filtering
     // In environment not supporting the textureLOD extension like EDGE. They are for internal use only.
     // They are at the level of the gl texture to benefit from the cache.

+ 4 - 27
src/Materials/Textures/renderTargetTexture.ts

@@ -987,7 +987,7 @@ export class RenderTargetTexture extends Texture {
     }
 
     /**
-     * Gets the number of views the corrisponding to the texture (eg. a MultiviewRenderTarget will have > 1)
+     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)
      */
     public getViewCount() {
         return 1;
@@ -1013,24 +1013,7 @@ export class MultiviewRenderTarget extends RenderTargetTexture {
      */
     constructor(public scene: Scene, size: number | { width: number, height: number } | { ratio: number } = 512) {
         super("multiview rtt", size, scene, false, true, InternalTexture.DATASOURCE_UNKNOWN, false, undefined, false, false, true, undefined, true);
-        if (!this.scene.getEngine().getCaps().multiview) {
-            this.dispose();
-            throw "Multiview is not supported";
-        }
-        var gl = scene.getEngine()._gl;
-
-        this._multiviewColorTexture = gl.createTexture();
-        gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._multiviewColorTexture);
-        (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, this.getRenderWidth(), this.getRenderHeight(), 2);
-
-        this._multivewDepthStencilTexture = gl.createTexture();
-        gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._multivewDepthStencilTexture);
-        (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, (gl as any).DEPTH32F_STENCIL8, this.getRenderWidth(), this.getRenderHeight(), 2);
-
-        var internalTexture = new InternalTexture(scene.getEngine(), InternalTexture.DATASOURCE_UNKNOWN, true);
-        internalTexture.width = this.getRenderWidth();
-        internalTexture.height = this.getRenderHeight();
-        internalTexture._framebuffer = gl.createFramebuffer();
+        var internalTexture = scene.getEngine().createMultiviewRenderTargetTexture(this.getRenderWidth(), this.getRenderHeight());
         this._texture = internalTexture;
     }
 
@@ -1042,17 +1025,11 @@ export class MultiviewRenderTarget extends RenderTargetTexture {
         if (!this._texture) {
             return;
         }
-        var gl: any = this.scene.getEngine()._gl;
-        var ext = this.scene.getEngine().getCaps().multiview;
-
-        this.scene.getEngine().bindFramebuffer(this._texture, undefined, undefined, undefined, this.ignoreCameraViewport);
-        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this._texture._framebuffer);
-        ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, this._multiviewColorTexture, 0, 0, 2);
-        ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, this._multivewDepthStencilTexture, 0, 0, 2);
+        this.scene.getEngine().bindMultiviewFramebuffer(this._texture);
     }
 
     /**
-     * Gets the number of views the corrisponding to the texture (eg. a MultiviewRenderTarget will have > 1)
+     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)
      */
     public getViewCount() {
         return 2;

+ 9 - 8
src/scene.ts

@@ -2537,14 +2537,12 @@ export class Scene extends AbstractScene implements IAnimatable {
 
     /**
      * Sets the current transform matrix
-     * @param view defines the View matrix to use
-     * @param projection defines the Projection matrix to use
+     * @param viewL defines the View matrix to use
+     * @param projectionL defines the Projection matrix to use
+     * @param viewR defines the right View matrix to use (if provided)
+     * @param projectionR defines the right Projection matrix to use (if provided)
      */
-    public setTransformMatrix(view: Matrix, projection: Matrix): void {
-        this._setMultiviewTransformMatrix(view, projection);
-    }
-
-    private _setMultiviewTransformMatrix(viewL: Matrix, projectionL: Matrix, viewR?: Matrix, projectionR?: Matrix): void {
+    public setTransformMatrix(viewL: Matrix, projectionL: Matrix, viewR?: Matrix, projectionR?: Matrix): void {
         if (this._viewUpdateFlag === viewL.updateFlag && this._projectionUpdateFlag === projectionL.updateFlag) {
             return;
         }
@@ -2570,6 +2568,9 @@ export class Scene extends AbstractScene implements IAnimatable {
             let otherCamera = this.activeCamera._alternateCamera;
             otherCamera.getViewMatrix().multiplyToRef(otherCamera.getProjectionMatrix(), Tmp.Matrix[0]);
             Frustum.GetRightPlaneToRef(Tmp.Matrix[0], this._frustumPlanes[3]); // Replace right plane by second camera right plane
+        } else if(viewR && projectionR){
+            viewR.multiplyToRef(projectionR, Tmp.Matrix[0]);
+            Frustum.GetRightPlaneToRef(Tmp.Matrix[0], this._frustumPlanes[3]); // Replace right plane by second camera right plane
         }
 
         if (this._sceneUbo.useUbo) {
@@ -4034,7 +4035,7 @@ export class Scene extends AbstractScene implements IAnimatable {
         this._bindFrameBuffer();
         var useMultiview = this.getEngine().getCaps().multiview && camera.outputRenderTarget && camera.outputRenderTarget.getViewCount() > 1;
         if (useMultiview) {
-            this._setMultiviewTransformMatrix(camera._rigCameras[0].getViewMatrix(), camera._rigCameras[0].getProjectionMatrix(), camera._rigCameras[1].getViewMatrix(), camera._rigCameras[1].getProjectionMatrix());
+            this.setTransformMatrix(camera._rigCameras[0].getViewMatrix(), camera._rigCameras[0].getProjectionMatrix(), camera._rigCameras[1].getViewMatrix(), camera._rigCameras[1].getProjectionMatrix());
         }else {
             this.updateTransformMatrix();