Skip to content

Commit

Permalink
Merge pull request #7134 from benaadams/reverse-depth
Browse files Browse the repository at this point in the history
Reverse Depth Buffer for Projection matrix
  • Loading branch information
deltakosh committed Nov 11, 2019
2 parents 973c804 + b8f2ca3 commit 2f967ec
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 13 deletions.
1 change: 1 addition & 0 deletions dist/preview release/what's new.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- 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 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

Expand Down
23 changes: 11 additions & 12 deletions src/Cameras/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,21 +719,20 @@ export class Camera extends Node {
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) {
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 {
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 {
var halfWidth = engine.getRenderWidth() / 2.0;
var halfHeight = engine.getRenderHeight() / 2.0;
Expand Down
12 changes: 11 additions & 1 deletion src/Engines/thinEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ export class ThinEngine {
/** Gets or sets a boolean indicating if the engine should validate programs after compilation */
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

/**
Expand Down Expand Up @@ -1136,7 +1141,12 @@ export class ThinEngine {
mode |= this._gl.COLOR_BUFFER_BIT;
}
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;
}
if (stencil) {
Expand Down
53 changes: 53 additions & 0 deletions src/Maths/math.vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4996,6 +4996,29 @@ export class Matrix {
result._updateIdentityStatus(false);
}

/**
* 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
* @param fov defines the horizontal field of view
Expand Down Expand Up @@ -5045,6 +5068,36 @@ export class Matrix {
result._updateIdentityStatus(false);
}

/**
* 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
* @param fov defines the field of view
Expand Down

0 comments on commit 2f967ec

Please sign in to comment.