我的视锥体剔除正在检测被剔除的对象,即使整个对象的边界球体尚未超出视锥体。就好像它认为边界球体的半径比实际的要小,尽管我确信情况并非如此。
到目前为止,我只是检查球体的顶部是否在截头体内,尽管通过更改截头体检查代码的 if 语句我可以得到相同的结果(当然是相反的)。
视锥体检查代码:
# vector to chunk from camera
chunk_vec = chunk.center - self.camera.pos
# chunk's y coordinate distance from camera on camera axes
y_dist = glm.dot(chunk_vec, self.camera.up) + CHUNK_BOUNDING_SPHERE_RADIUS
# chunk's z coordinate distance from camera on camera axes
z_dist = glm.dot(chunk_vec, self.camera.forward)
HIGHEST_ALLOWED_THETA = VFOV / 2
theta = glm.atan(y_dist / z_dist)
print(glm.degrees(theta), glm.degrees(HIGHEST_ALLOWED_THETA))
if theta <= HIGHEST_ALLOWED_THETA:
print('render')
else:
print('cull')
边界球半径计算:(我非常有信心,尽管这似乎是主要嫌疑人,但这不是这里的错误,因为我的边界球渲染完全适合,并且我已经多次重新检查了此计算)
length = glm.sqrt(glm.pow(CHUNK_LENGTH_VOXELS * VOXEL_SIZE / 2, 2) * 2)
height = CHUNK_HEIGHT_VOXELS * VOXEL_SIZE / 2
CHUNK_BOUNDING_SPHERE_RADIUS = glm.sqrt(
glm.pow(length, 2) + glm.pow(height, 2)
)
当我的视锥体检查代码确定边界球体不再位于视锥体内时,还剩下多少边界球体的示例:(请注意,我的代码未考虑的球体比例无论在什么情况下都不会变化物体的距离或相机的位置) https://imgur.com/a/Y4gKiSI
我的对象及其边界球(为了更好地理解场景): https://imgur.com/a/Jk0Kjcf
我可以手动校准半径值以获得完美的结果,尽管这显然是一个不理想的解决方案,我希望了解我的错误是什么。
编辑:
投影矩阵计算:
ASPECT_RATIO = 16 / 9
NEAR = 0.1
FAR = 20000
FOV = 70
VFOV = glm.radians(FOV)
HFOV = 2 * glm.atan(glm.tan(VFOV * 0.5) * ASPECT_RATIO)
self.proj_mat = glm.perspective(
VFOV, ASPECT_RATIO, NEAR, FAR
)
视图矩阵计算:(在相机类中)
yaw_change, pitch_change = pg.mouse.get_rel()
self.yaw -= yaw_change * MOUSE_SENSITIVITY
self.pitch -= pitch_change * MOUSE_SENSITIVITY
self.pitch = glm.clamp(self.pitch, -80, 80)
yaw = glm.radians(self.yaw)
pitch = glm.radians(self.pitch)
yaw_sin = glm.sin(yaw)
yaw_cos = glm.cos(yaw)
pitch_sin = glm.sin(pitch)
pitch_cos = glm.cos(pitch)
self.right = glm.normalize(glm.vec3(yaw_cos, 0, -yaw_sin))
self.up = glm.normalize(glm.vec3(yaw_sin * pitch_sin, pitch_cos, yaw_cos * pitch_sin))
self.forward = glm.normalize(glm.vec3(yaw_sin * pitch_cos, -pitch_sin, pitch_cos * yaw_cos))
self.view_mat = glm.mat4(
glm.vec4(self.right.x, self.up.x, self.forward.x, 0),
glm.vec4(self.right.y, self.up.y, self.forward.y, 0),
glm.vec4(self.right.z, self.up.z, self.forward.z, 0),
glm.vec4(-glm.dot(self.right, self.pos), -glm.dot(self.up, self.pos), -glm.dot(self.forward, self.pos), 1)
)
想通了。原来我不太明白什么是点积。本质上,我将点积视为向量之间的实际距离。它们只能用于获取此处轴的比率。