c - OpenGL:我自己实现的截锥体函数导致黑屏
问题描述
我目前正在开发一个涉及大量相机移动的应用程序。我已经编写了我自己的lookAt
函数,它似乎工作正常。我现在想实现我自己的frustum
功能。目前我有一个以原点为中心的 1x1x1 立方体。我正在尝试更改我的视图,以便我可以在所有轴上看到 -2 到 2,以检查我的功能是否正常工作。这是我的功能的代码:
mat4 frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
{
mat4 f;
f.x.x = 2*near/(right-left);
f.y.x = 0;
f.z.x = (right + left)/(right - left);
f.w.x = 0;
f.x.y = 0;
f.y.y = 2*near/(top-bottom);
f.z.y = (top + bottom)/(top - bottom);
f.w.y = 0;
f.x.z = 0;
f.y.z = 0;
f.z.z = (far+near)/(far-near);
f.w.z = 2*(far*near)/(far-near);
f.x.w = 0;
f.y.w = 0;
f.z.w = -1.0;
f.w.w = 0;
return f;
}
我传入近、右和上为 2。远、左和下传为 -2。当我用这些参数调用我的函数时,它返回以下矩阵:
┏ -1.000000 0.000000 0.000000 0.000000
┃ 0.000000 -1.000000 0.000000 0.000000
┃ 0.000000 0.000000 0.000000 -2.000000
┗ 0.000000 0.000000 -1.000000 0.000000
我不确定这是否正确,我的问题出在其他地方,或者函数中的某些内容是否关闭。
解决方案
我传入近、右和上为 2。远、左和下传为 -2。
近平面的负值无效。在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口中的 2D 点的映射。透视投影矩阵定义了一个视锥体:
因此近平面和远平面必须是正值:
0 < near < far
透视投影矩阵可以由平截头体定义。
距离left
、right
和是近平面bottom
上top
从视图中心到截锥体侧面的距离。near
并far
指定到平截头体的近平面和远平面的距离。
r = right, l = left, b = bottom, t = top, n = near, f = far
x: 2*n/(r-l) 0 0 0
y: 0 2*n/(t-b) 0 0
z: (r+l)/(r-l) (t+b)/(t-b) -(f+n)/(f-n) -1
t: 0 0 -2*f*n/(f-n) 0
投影矩阵是从视图空间到剪辑空间的变换,分别是归一化的设备空间。在 OpenGL 中,视图空间通常是右手坐标系,而标准化的设备空间是左手坐标系。投影矩阵镜像z轴以实现变换。因此,z 分量必须倒置:
mat4 frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
{
mat4 f;
f.x.x = 2*near/(right-left);
f.y.x = 0;
f.z.x = (right + left)/(right - left);
f.w.x = 0;
f.x.y = 0;
f.y.y = 2*near/(top-bottom);
f.z.y = (top + bottom)/(top - bottom);
f.w.y = 0;
f.x.z = 0;
f.y.z = 0;
f.z.z = - (far+near)/(far-near);
f.w.z = - 2*(far*near)/(far-near);
f.x.w = 0;
f.y.w = 0;
f.z.w = -1.0;
f.w.w = 0;
return f;
}
您需要确保几何体位于视锥体的近平面和远平面之间。所有超出平截头体的几何体都被剪裁掉。
请注意,视图空间 Z 坐标为 0 的几何图形将被剪裁,因为0 < near < far
.
推荐阅读
- python - 使用 Python 解析 XML 时跳过“嵌套标签”
- yii - Yii2 ValidatePage 在错误的页码上给出空输出
- python - 使用flask sqlalchemy将数据从源数据库导入目标数据库
- c# - 一次读取 MQ 中的所有消息
- drupal - Drupal 8:如何基于 Ajax 回调生成选项
- python - 在python中读取.dat文件
- flutter - 在颤动中设置小部件对齐方式
- types - 类型错误将中缀表达式“或”解析为 std.STANDARD.BOOLEAN
- c++ - Directx 12:在两个进程之间共享图形内存
- javascript - 可观察的总部。什么是错