Correct frustum culling, finally!
This commit is contained in:
parent
78eebc1e17
commit
1633957d07
@ -405,23 +405,15 @@ pub fn finish(self: *Render) void {
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program);
|
||||
gl.bindVertexArray(self.mesh_vao);
|
||||
|
||||
//const inv_view_mat = self.camera.view_mat.inv();
|
||||
// const world_camera_frustum = math.Frustum.perspective(
|
||||
// self.camera.fovy,
|
||||
// self.camera.aspect,
|
||||
// self.camera.near,
|
||||
// self.camera.far,
|
||||
// ).transform(&inv_view_mat);
|
||||
|
||||
const view_proj = projection.mul(self.camera.view_mat);
|
||||
const world_camera_frustum = math.Frustum.new(view_proj);
|
||||
|
||||
var rendered_count: usize = 0;
|
||||
for (self.command_buffer[0..self.command_count]) |*cmd| {
|
||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||
const aabb = math.AABB.fromMinMax(mesh.aabb.min, mesh.aabb.max);
|
||||
|
||||
const mvp = view_proj.mul(cmd.transform);
|
||||
if (!math.checkAABBIntersectionNDC(&aabb, &mvp)) {
|
||||
if (!world_camera_frustum.intersectAABB(aabb.transform(cmd.transform))) {
|
||||
continue;
|
||||
}
|
||||
rendered_count += 1;
|
||||
|
@ -65,14 +65,13 @@ pub const FreeLookCamera = struct {
|
||||
self.yaw += look.x();
|
||||
self.pitch += look.y();
|
||||
// First rotate pitch, then yaw
|
||||
const rot = Mat4.fromRotation(self.pitch, Vec3.left()).mul(Mat4.fromRotation(self.yaw, Vec3.up()));
|
||||
const rot = Mat4.fromRotation(self.pitch, Vec3.right()).mul(Mat4.fromRotation(self.yaw, Vec3.up()));
|
||||
|
||||
// First 3 of transform matrix are: right, up, forward
|
||||
const left = Vec3.new(rot.data[0][0], rot.data[1][0], rot.data[2][0]);
|
||||
const right = Vec3.new(rot.data[0][0], rot.data[1][0], rot.data[2][0]);
|
||||
const up = Vec3.new(rot.data[0][1], rot.data[1][1], rot.data[2][1]);
|
||||
const forward = Vec3.new(rot.data[0][2], rot.data[1][2], rot.data[2][2]);
|
||||
const forward = Vec3.new(-rot.data[0][2], -rot.data[1][2], -rot.data[2][2]);
|
||||
|
||||
const movement = left.scale(-move.x()).add(forward.scale(move.y())).add(up.scale(move.z()));
|
||||
const movement = right.scale(move.x()).add(forward.scale(move.y())).add(up.scale(move.z()));
|
||||
|
||||
self.pos = self.pos.add(movement.scale(self.move_speed * dt));
|
||||
|
||||
|
66
src/math.zig
66
src/math.zig
@ -22,8 +22,9 @@ pub const Plane = struct {
|
||||
// x, y, z - normal, w - distance
|
||||
nd: Vec4 = Vec4.up(),
|
||||
|
||||
pub fn new(normal: Vec3, distance: f32) Plane {
|
||||
return .{ .nd = normal.norm().toVec4(distance) };
|
||||
pub fn new(normal_d: Vec4) Plane {
|
||||
const scale = 1.0 / normal_d.toVec3().length();
|
||||
return .{ .nd = normal_d.scale(scale) };
|
||||
}
|
||||
|
||||
pub fn transform(self: *const Plane, matrix: *const Mat4) Plane {
|
||||
@ -80,30 +81,30 @@ pub const Frustum = struct {
|
||||
near: Plane,
|
||||
far: Plane,
|
||||
|
||||
// Returns a frustum in view space
|
||||
pub fn perspective(fovy: f32, aspect: f32, z_near: f32, z_far: f32) Frustum {
|
||||
const half_height = @tan(za.toRadians(fovy) * 0.5);
|
||||
const half_width = half_height * aspect;
|
||||
/// Extracts frustum planes from matrices using Gribb-Hartmann method
|
||||
/// If you pass in a projection matrix planes will be in view space.
|
||||
/// If you pass in a view-projection matrix planes will be in world space.
|
||||
/// If you pass in a model-view-projection matrix planes will be in model space.
|
||||
pub fn new(mat: Mat4) Frustum {
|
||||
const row1 = Vec4.new(mat.data[0][0], mat.data[1][0], mat.data[2][0], mat.data[3][0]);
|
||||
const row2 = Vec4.new(mat.data[0][1], mat.data[1][1], mat.data[2][1], mat.data[3][1]);
|
||||
const row3 = Vec4.new(mat.data[0][2], mat.data[1][2], mat.data[2][2], mat.data[3][2]);
|
||||
const row4 = Vec4.new(mat.data[0][3], mat.data[1][3], mat.data[2][3], mat.data[3][3]);
|
||||
|
||||
const nw = Vec3.new(-half_width, half_height, 1).norm();
|
||||
const ne = Vec3.new(half_width, half_height, 1).norm();
|
||||
const se = Vec3.new(half_width, -half_height, 1).norm();
|
||||
const sw = Vec3.new(-half_width, -half_height, 1).norm();
|
||||
|
||||
const top = nw.cross(ne);
|
||||
const right = ne.cross(se);
|
||||
const bottom = se.cross(sw);
|
||||
const left = sw.cross(nw);
|
||||
const near = Vec3.new(0, 0, -1);
|
||||
const far = Vec3.new(0, 0, 1);
|
||||
const left = row4.add(row1);
|
||||
const right = row4.sub(row1);
|
||||
const bottom = row4.add(row2);
|
||||
const top = row4.sub(row2);
|
||||
const near = row4.add(row3);
|
||||
const far = row4.sub(row3);
|
||||
|
||||
return .{
|
||||
.top = Plane.new(top, 0),
|
||||
.right = Plane.new(right, 0),
|
||||
.bottom = Plane.new(bottom, 0),
|
||||
.left = Plane.new(left, 0),
|
||||
.near = Plane.new(near, z_near),
|
||||
.far = Plane.new(far, -z_far),
|
||||
.top = Plane.new(top),
|
||||
.right = Plane.new(right),
|
||||
.bottom = Plane.new(bottom),
|
||||
.left = Plane.new(left),
|
||||
.near = Plane.new(near),
|
||||
.far = Plane.new(far),
|
||||
};
|
||||
}
|
||||
|
||||
@ -123,13 +124,24 @@ pub const Frustum = struct {
|
||||
}
|
||||
|
||||
pub fn intersectAABB(self: *const Frustum, aabb: AABB) bool {
|
||||
var outside_top_plane = true;
|
||||
var outside_bottom_plane = true;
|
||||
var outside_left_plane = true;
|
||||
var outside_right_plane = true;
|
||||
var outside_near_plane = true;
|
||||
var outside_far_plane = true;
|
||||
inline for (box_corners) |corner| {
|
||||
if (self.intersectPoint(aabb.origin.add(aabb.extents.mul(corner)))) {
|
||||
return true;
|
||||
}
|
||||
const p = aabb.origin.add(aabb.extents.mul(corner));
|
||||
|
||||
outside_top_plane = outside_top_plane and self.top.isUnder(p);
|
||||
outside_bottom_plane = outside_bottom_plane and self.bottom.isUnder(p);
|
||||
outside_left_plane = outside_left_plane and self.left.isUnder(p);
|
||||
outside_right_plane = outside_right_plane and self.right.isUnder(p);
|
||||
outside_near_plane = outside_near_plane and self.near.isUnder(p);
|
||||
outside_far_plane = outside_far_plane and self.far.isUnder(p);
|
||||
}
|
||||
|
||||
return false;
|
||||
return !(outside_left_plane or outside_right_plane or outside_bottom_plane or outside_top_plane or outside_near_plane or outside_far_plane);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user