使用视锥体的 3D 到 2D 投影存在平移问题
3D to 2D projection using view frustum has issues with translation
我需要创建这个软件光栅化器,给定投影 (P
)、视图 (V
) 和模型 (M
) 矩阵,可以创建一个二维图像点云 (pc
) 从位图格式(单色位图)的给定角度。
我已经掌握了数学知识(而且大部分情况似乎都有效):
- 变换点云的点
pc' = (P x V x M) x pc
(注意点云已经在齐次系统中了)
- 对于每个点,将所有分量除以其
w
(同时注意丢弃 w
接近于零的点。
- 丢弃落在视锥之外的点(通过使用 here 中描述的方法从
P
中提取视锥平面)
- 使用
(x + 1) * imageWidth / 2
和 (-y + 1) * imageHeight / 2
将每个点的 x
和 y
坐标转换为屏幕坐标(以获得正确的 y 坐标)。
- 使用
(int)y * imageWidth + (int)x
(带边界检查)将生成的 x
和 y
坐标映射到位图线性索引。
似乎一切正常:我得到了精确的位图,就像我用 OpenGL 渲染它一样,通过任意四元数旋转点云仍然给出有效结果。
在矩阵 M
中有一个翻译组件之前一切都很好!只要我有最少量的平移,图像就会中断:点云会严重扭曲(就好像对它应用了非仿射变换一样)。沿哪个方向应用平移并不重要,任何平移都会弄乱一切,直到点云不再可识别。起初我虽然我的模型矩阵被转置(导致非仿射变换),但事实并非如此。
如果需要,我可以 post 一些代码,但是鉴于以上概述,我是否遗漏了什么??有什么需要特别注意的地方吗??
这个问题太愚蠢了,我很惭愧浪费了这么多时间。
原来我的点云中的一些点有错误的 w
个组件。我没有 运行 解决 OpenGL 方面的任何问题,因为着色器手动将所有 w
设置为 1。在光栅器方面,错误的 w
导致的点位于到相机的距离更长,投影到错误的透视位置。
我使用的测试球体没有任何问题,因为它们具有正确的 w
个组件。
编辑:
只是想我还要提到这一点:不需要提取视锥体平面来确定投影点是否落在视锥体内。可以通过确定变换点 (x', y', z', w')
中的所有 x'
、y'
和 z'
分量(即乘以矩阵 P x V x M
后)是否下降来简单地执行此检查在 w'
和 -w'
范围内。如果所有三个组件都落在该范围内,则该点可见,否则该点在视锥之外。
我需要创建这个软件光栅化器,给定投影 (P
)、视图 (V
) 和模型 (M
) 矩阵,可以创建一个二维图像点云 (pc
) 从位图格式(单色位图)的给定角度。
我已经掌握了数学知识(而且大部分情况似乎都有效):
- 变换点云的点
pc' = (P x V x M) x pc
(注意点云已经在齐次系统中了) - 对于每个点,将所有分量除以其
w
(同时注意丢弃w
接近于零的点。 - 丢弃落在视锥之外的点(通过使用 here 中描述的方法从
P
中提取视锥平面) - 使用
(x + 1) * imageWidth / 2
和(-y + 1) * imageHeight / 2
将每个点的x
和y
坐标转换为屏幕坐标(以获得正确的 y 坐标)。 - 使用
(int)y * imageWidth + (int)x
(带边界检查)将生成的x
和y
坐标映射到位图线性索引。
似乎一切正常:我得到了精确的位图,就像我用 OpenGL 渲染它一样,通过任意四元数旋转点云仍然给出有效结果。
在矩阵 M
中有一个翻译组件之前一切都很好!只要我有最少量的平移,图像就会中断:点云会严重扭曲(就好像对它应用了非仿射变换一样)。沿哪个方向应用平移并不重要,任何平移都会弄乱一切,直到点云不再可识别。起初我虽然我的模型矩阵被转置(导致非仿射变换),但事实并非如此。
如果需要,我可以 post 一些代码,但是鉴于以上概述,我是否遗漏了什么??有什么需要特别注意的地方吗??
这个问题太愚蠢了,我很惭愧浪费了这么多时间。
原来我的点云中的一些点有错误的 w
个组件。我没有 运行 解决 OpenGL 方面的任何问题,因为着色器手动将所有 w
设置为 1。在光栅器方面,错误的 w
导致的点位于到相机的距离更长,投影到错误的透视位置。
我使用的测试球体没有任何问题,因为它们具有正确的 w
个组件。
编辑:
只是想我还要提到这一点:不需要提取视锥体平面来确定投影点是否落在视锥体内。可以通过确定变换点 (x', y', z', w')
中的所有 x'
、y'
和 z'
分量(即乘以矩阵 P x V x M
后)是否下降来简单地执行此检查在 w'
和 -w'
范围内。如果所有三个组件都落在该范围内,则该点可见,否则该点在视锥之外。