使用视锥体的3D到2D投影存在平移问题
3D to 2D projection using view frustum has issues with translation
我需要创建这个软件光栅化器,给定投影(P
),视图(V
)和模型(M
)矩阵,可以从给定的角度以位图格式(单色位图)创建点云(pc
)的2D图像。
我已经把数学计算下来了(事情似乎在大多数情况下都是有效的):
- 变换点云的点
pc' = (P x V x M) x pc
(注意点云已经是同质系统) - 对于每个点,将所有组件除以其
w
(同时小心丢弃w
接近于零的点)。 - 丢弃落在视图截锥体之外的点(通过使用这里描述的方法从
P
中提取截锥体平面) - 使用
(x + 1) * imageWidth / 2
和(-y + 1) * imageHeight / 2
将每个点的x
和y
坐标转换为屏幕坐标(以获得正确的y坐标)。 - 将
x
和y
坐标映射到使用(int)y * imageWidth + (int)x
(带绑定检查)的位图线性索引。
看起来一切都很好:我得到了精确的位图,就好像我用OpenGL渲染它一样,通过任意四元数旋转点云仍然给出了有效的结果。
事情很好,直到我有一个矩阵M
翻译组件!只要我有一点点的平移,图像就会破裂:点云被严重扭曲(就好像对它进行了非仿射变换)。沿着哪个方向平移并不重要,任何平移都会使一切变得混乱,直到点云不再可识别。起初,我认为我的模型矩阵是转置的(导致非仿射变换),但情况似乎并非如此。
这个问题太愚蠢了,我很惭愧浪费了这么多时间。
结果是我的点云中的一些点有错误的w
组件。我在OpenGL方面没有遇到任何问题,因为着色器手动将所有w
设置为1。在光栅化方面,错误的w
会导致距离相机较远的点投射到错误的透视位置。
我使用的测试球体没有任何问题,因为它们有正确的w
组件。
我还想提一下:没有必要提取视锥面来确定投影点是否落在视锥内。可以简单地通过确定变换点(x', y', z', w')
(即乘以矩阵P x V x M
后)中的所有x'
, y'
和z'
分量是否落在w'
和-w'
范围内来执行此检查。如果三个组件都在这个范围内,则该点是可见的,否则该点在视锥台之外。
相关文章:
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 如何将分支添加到已存在的TTree:ROOT
- 地图计数确实很重要,或者只是检查是否存在
- 通用C++/Python 多语言的存在
- 使用视锥体的3D到2D投影存在平移问题