فهرست منبع

Merge pull request #7134 from benaadams/reverse-depth

Reverse Depth Buffer for Projection matrix
David Catuhe 5 سال پیش
والد
کامیت
2f967ecd16
4فایلهای تغییر یافته به همراه76 افزوده شده و 13 حذف شده
  1. 1 0
      dist/preview release/what's new.md
  2. 11 12
      src/Cameras/camera.ts
  3. 11 1
      src/Engines/thinEngine.ts
  4. 53 0
      src/Maths/math.vector.ts

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

@@ -15,6 +15,7 @@
   - WebXR webVR parity helpers (Vive, WMR, Oculus Rift) ([TrevorDev](https://github.com/TrevorDev))
   - WebXR webVR parity helpers (Vive, WMR, Oculus Rift) ([TrevorDev](https://github.com/TrevorDev))
 - Added support for Offscreen canvas [Doc](https://doc.babylonjs.com/how_to/using_offscreen_canvas) ([Deltakosh](https://github.com/deltakosh/)
 - Added support for Offscreen canvas [Doc](https://doc.babylonjs.com/how_to/using_offscreen_canvas) ([Deltakosh](https://github.com/deltakosh/)
 - Added support for multiple canvases with one engine [Doc](https://doc.babylonjs.com/how_to/multi_canvases) ([Deltakosh](https://github.com/deltakosh/)
 - Added support for multiple canvases with one engine [Doc](https://doc.babylonjs.com/how_to/multi_canvases) ([Deltakosh](https://github.com/deltakosh/)
+- Added useReverseDepthBuffer to Engine which can provide greater z depth for distant objects without the cost of a logarithmic depth buffer ([BenAdams](https://github.com/benaadams/))
 
 
 ## Updates
 ## Updates
 
 

+ 11 - 12
src/Cameras/camera.ts

@@ -719,21 +719,20 @@ export class Camera extends Node {
                 this.minZ = 0.1;
                 this.minZ = 0.1;
             }
             }
 
 
+            const reverseDepth = engine.useReverseDepthBuffer;
+            let getProjectionMatrix: (fov: number, aspect: number, znear: number, zfar: number, result: Matrix, isVerticalFovFixed: boolean) => void;
             if (scene.useRightHandedSystem) {
             if (scene.useRightHandedSystem) {
-                Matrix.PerspectiveFovRHToRef(this.fov,
-                    engine.getAspectRatio(this),
-                    this.minZ,
-                    this.maxZ,
-                    this._projectionMatrix,
-                    this.fovMode === Camera.FOVMODE_VERTICAL_FIXED);
+                getProjectionMatrix = reverseDepth ? Matrix.PerspectiveFovReverseRHToRef : Matrix.PerspectiveFovRHToRef;
             } else {
             } else {
-                Matrix.PerspectiveFovLHToRef(this.fov,
-                    engine.getAspectRatio(this),
-                    this.minZ,
-                    this.maxZ,
-                    this._projectionMatrix,
-                    this.fovMode === Camera.FOVMODE_VERTICAL_FIXED);
+                getProjectionMatrix = reverseDepth ? Matrix.PerspectiveFovReverseLHToRef : Matrix.PerspectiveFovLHToRef;
             }
             }
+
+            getProjectionMatrix(this.fov,
+                engine.getAspectRatio(this),
+                this.minZ,
+                this.maxZ,
+                this._projectionMatrix,
+                this.fovMode === Camera.FOVMODE_VERTICAL_FIXED);
         } else {
         } else {
             var halfWidth = engine.getRenderWidth() / 2.0;
             var halfWidth = engine.getRenderWidth() / 2.0;
             var halfHeight = engine.getRenderHeight() / 2.0;
             var halfHeight = engine.getRenderHeight() / 2.0;

+ 11 - 1
src/Engines/thinEngine.ts

@@ -201,6 +201,11 @@ export class ThinEngine {
     /** Gets or sets a boolean indicating if the engine should validate programs after compilation */
     /** Gets or sets a boolean indicating if the engine should validate programs after compilation */
     public validateShaderPrograms = false;
     public validateShaderPrograms = false;
 
 
+    /**
+     * Gets or sets a boolean indicating if depth buffer should be reverse, going from far to near.
+     * This can provide greater z depth for distant objects.
+     */
+    public useReverseDepthBuffer = false;
     // Uniform buffers list
     // Uniform buffers list
 
 
     /**
     /**
@@ -1136,7 +1141,12 @@ export class ThinEngine {
             mode |= this._gl.COLOR_BUFFER_BIT;
             mode |= this._gl.COLOR_BUFFER_BIT;
         }
         }
         if (depth) {
         if (depth) {
-            this._gl.clearDepth(1.0);
+            if (this.useReverseDepthBuffer) {
+                this._depthCullingState.depthFunc = this._gl.GREATER;
+                this._gl.clearDepth(0.0);
+            } else {
+                this._gl.clearDepth(1.0);
+            }
             mode |= this._gl.DEPTH_BUFFER_BIT;
             mode |= this._gl.DEPTH_BUFFER_BIT;
         }
         }
         if (stencil) {
         if (stencil) {

+ 53 - 0
src/Maths/math.vector.ts

@@ -4997,6 +4997,29 @@ export class Matrix {
     }
     }
 
 
     /**
     /**
+     * Stores a left-handed perspective projection into a given matrix with depth reversed
+     * @param fov defines the horizontal field of view
+     * @param aspect defines the aspect ratio
+     * @param znear defines the near clip plane
+     * @param zfar not used as infinity is used as far clip
+     * @param result defines the target matrix
+     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally
+     */
+    public static PerspectiveFovReverseLHToRef(fov: number, aspect: number, znear: number, zfar: number, result: Matrix, isVerticalFovFixed = true): void {
+        let t = 1.0 / (Math.tan(fov * 0.5));
+        let a = isVerticalFovFixed ? (t / aspect) : t;
+        let b = isVerticalFovFixed ? t : (t * aspect);
+        Matrix.FromValuesToRef(
+            a, 0.0, 0.0, 0.0,
+            0.0, b, 0.0, 0.0,
+            0.0, 0.0, -znear, 1.0,
+            0.0, 0.0, 1.0, 0.0,
+            result
+        );
+        result._updateIdentityStatus(false);
+    }
+
+    /**
      * Creates a right-handed perspective projection matrix
      * Creates a right-handed perspective projection matrix
      * @param fov defines the horizontal field of view
      * @param fov defines the horizontal field of view
      * @param aspect defines the aspect ratio
      * @param aspect defines the aspect ratio
@@ -5046,6 +5069,36 @@ export class Matrix {
     }
     }
 
 
     /**
     /**
+     * Stores a right-handed perspective projection into a given matrix
+     * @param fov defines the horizontal field of view
+     * @param aspect defines the aspect ratio
+     * @param znear defines the near clip plane
+     * @param zfar not used as infinity is used as far clip
+     * @param result defines the target matrix
+     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally
+     */
+    public static PerspectiveFovReverseRHToRef(fov: number, aspect: number, znear: number, zfar: number, result: Matrix, isVerticalFovFixed = true): void {
+        //alternatively this could be expressed as:
+        //    m = PerspectiveFovLHToRef
+        //    m[10] *= -1.0;
+        //    m[11] *= -1.0;
+
+        let t = 1.0 / (Math.tan(fov * 0.5));
+        let a = isVerticalFovFixed ? (t / aspect) : t;
+        let b = isVerticalFovFixed ? t : (t * aspect);
+
+        Matrix.FromValuesToRef(
+            a, 0.0, 0.0, 0.0,
+            0.0, b, 0.0, 0.0,
+            0.0, 0.0, -znear, -1.0,
+            0.0, 0.0, -1.0, 0.0,
+            result
+        );
+
+        result._updateIdentityStatus(false);
+    }
+
+    /**
      * Stores a perspective projection for WebVR info a given matrix
      * Stores a perspective projection for WebVR info a given matrix
      * @param fov defines the field of view
      * @param fov defines the field of view
      * @param znear defines the near clip plane
      * @param znear defines the near clip plane