Skip to content

Commit 4f92b6f

Browse files
committed
Add mat4.projectionZO, which is appropriate for WebGPU's normalized device coordinates
1 parent 93d9f75 commit 4f92b6f

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

src/mat4.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,8 @@ export function frustum(out, left, right, bottom, top, near, far) {
14961496

14971497
/**
14981498
* Generates a perspective projection matrix with the given bounds.
1499+
* The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
1500+
* which matches WebGL/OpenGL's clip volume.
14991501
* Passing null/undefined/no value for far will generate infinite projection matrix.
15001502
*
15011503
* @param {mat4} out mat4 frustum matrix will be written into
@@ -1505,7 +1507,7 @@ export function frustum(out, left, right, bottom, top, near, far) {
15051507
* @param {number} far Far bound of the frustum, can be null or Infinity
15061508
* @returns {mat4} out
15071509
*/
1508-
export function perspective(out, fovy, aspect, near, far) {
1510+
export function perspectiveNO(out, fovy, aspect, near, far) {
15091511
let f = 1.0 / Math.tan(fovy / 2),
15101512
nf;
15111513
out[0] = f / aspect;
@@ -1533,6 +1535,53 @@ export function perspective(out, fovy, aspect, near, far) {
15331535
return out;
15341536
}
15351537

1538+
/**
1539+
* Alias for {@link mat4.perspectiveNO}
1540+
* @function
1541+
*/
1542+
export const perspective = perspectiveNO;
1543+
1544+
/**
1545+
* Generates a perspective projection matrix suitable for WebGPU with the given bounds.
1546+
* The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
1547+
* which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
1548+
* Passing null/undefined/no value for far will generate infinite projection matrix.
1549+
*
1550+
* @param {mat4} out mat4 frustum matrix will be written into
1551+
* @param {number} fovy Vertical field of view in radians
1552+
* @param {number} aspect Aspect ratio. typically viewport width/height
1553+
* @param {number} near Near bound of the frustum
1554+
* @param {number} far Far bound of the frustum, can be null or Infinity
1555+
* @returns {mat4} out
1556+
*/
1557+
export function perspectiveZO(out, fovy, aspect, near, far) {
1558+
let f = 1.0 / Math.tan(fovy / 2),
1559+
nf;
1560+
out[0] = f / aspect;
1561+
out[1] = 0;
1562+
out[2] = 0;
1563+
out[3] = 0;
1564+
out[4] = 0;
1565+
out[5] = f;
1566+
out[6] = 0;
1567+
out[7] = 0;
1568+
out[8] = 0;
1569+
out[9] = 0;
1570+
out[11] = -1;
1571+
out[12] = 0;
1572+
out[13] = 0;
1573+
out[15] = 0;
1574+
if (far != null && far !== Infinity) {
1575+
nf = 1 / (near - far);
1576+
out[10] = far * nf;
1577+
out[14] = far * near * nf;
1578+
} else {
1579+
out[10] = -1;
1580+
out[14] = -near;
1581+
}
1582+
return out;
1583+
}
1584+
15361585
/**
15371586
* Generates a perspective projection matrix with the given field of view.
15381587
* This is primarily useful for generating projection matrices to be used

0 commit comments

Comments
 (0)