Optimize renderer
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
// what the camera can see: the six planes around it, taken from its view projection matrix (gl-matrix's column major
|
||||
// order, with webgpu's 0 to 1 depth). a box is out of view when it's entirely behind one of them
|
||||
export class Frustum {
|
||||
// a, b, c, d per plane, where a * x + b * y + c * z + d >= 0 is the inside
|
||||
#planes = new Float32Array(24);
|
||||
|
||||
update(m: Readonly<Float32Array>) {
|
||||
const planes = this.#planes;
|
||||
const set = (i: number, a: number, b: number, c: number, d: number) => {
|
||||
planes[i * 4] = a;
|
||||
planes[i * 4 + 1] = b;
|
||||
planes[i * 4 + 2] = c;
|
||||
planes[i * 4 + 3] = d;
|
||||
};
|
||||
// row r of the matrix is m[r], m[4 + r], m[8 + r], m[12 + r]
|
||||
set(0, m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]); // left
|
||||
set(1, m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]); // right
|
||||
set(2, m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]); // bottom
|
||||
set(3, m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]); // top
|
||||
set(4, m[2], m[6], m[10], m[14]); // near, depth 0
|
||||
set(5, m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]); // far
|
||||
}
|
||||
|
||||
// whether any of the box can be seen. may say yes for boxes just outside a corner, never no for one inside
|
||||
intersects_box(min_x: number, min_y: number, min_z: number, max_x: number, max_y: number, max_z: number) {
|
||||
const planes = this.#planes;
|
||||
for (let i = 0; i < 24; i += 4) {
|
||||
const a = planes[i];
|
||||
const b = planes[i + 1];
|
||||
const c = planes[i + 2];
|
||||
// the box's corner furthest along the plane's normal
|
||||
const x = a > 0 ? max_x : min_x;
|
||||
const y = b > 0 ? max_y : min_y;
|
||||
const z = c > 0 ? max_z : min_z;
|
||||
if (a * x + b * y + c * z + planes[i + 3] < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user