透视投影 - 如何投影“相机”后面的点?
我正在用 Java 编写自己的软件光栅器,但遇到了一些麻烦...请看一下示例图像:
这个示例只是在平面上绘制简单的方形网格。一切正常,直到我将相机移得足够近,使某些点移动到它后面。之后,它们不再正确投影,如您所见(垂直线 - 应该位于相机后面的点被投影到屏幕顶部)。
我的变换矩阵和向量与 DirectX 使用的矩阵和向量相同(用于投影的 PerspectiveFovLH,用于相机的 LookAtLH)。
我使用以下变换方法来投影 3D 点:
- 创建要变换的 3D 矢量。
- 向量乘以 ViewProjection 矩阵。
之后,使用以下方法将点转换为屏幕:
// 'vector' 是投影空间中的输入向量 // 投影到屏幕 双 vX = 矢量.x / 矢量.z; 双 vY = 向量.y / 向量.z; //翻译 //surfaceW是渲染窗口的宽度,surfaceH是高度。 vX = (( vX + 1.0f) / 2.0f) * 表面W; vY = ((-vY + 1.0f) / 2.0f) * 表面H; 返回新的 Vector3(vX, vY, 矢量.z);
正如我之前所说,它工作正常,直到点移动到相机后面。事实是,我可以弄清楚该点何时位于相机后面(通过测试最终变换后的 Z 值),但由于我正在绘制线条和其他基于线条的对象,所以我不能跳过该点。
然后我尝试根据 MSDN 上的The Direct3D Transformation Pipeline文章设置我的转换管道。
不幸的是,我也没有任何运气(相同的结果),所以任何帮助将不胜感激,因为我有点陷入这个困境。
谢谢。
此致, 亚历克斯
I'm writing my own software rasterizer in Java, and I ran into some trouble with it... take a look at a sample image, please:
This sample just draw simple square grid on a plane. Everything works fine until I move camera close enough for some points to move behind it. After that, they're no longer projected correctly, as you can see (vertical lines - points that should be behind camera are projected on top of the screen).
My transformation matrices and vectors are same ones DirectX is using (PerspectiveFovLH for projection, LookAtLH for camera).
I'm using following transformation method to project 3D point:
- 3D vector to be transformed is created.
- Vector is multiplied by ViewProjection matrix.
After that, point is transformed to screen using following method:
// 'vector' is input vector in projection space // projection to screen double vX = vector.x / vector.z; double vY = vector.y / vector.z; //translate //surfaceW is width and surfaceH is height of the rendering window. vX = (( vX + 1.0f) / 2.0f) * surfaceW; vY = ((-vY + 1.0f) / 2.0f) * surfaceH; return new Vector3(vX, vY, vector.z);
As I said earlier, it works fine until point moves behind camera. The fact is, I can figure out when the point is behind camera (by testing it's Z value after final transform), but since I'm drawing lines and other line based objects, I can't just skip that point.
Then I tried setting my transformation pipeline according to The Direct3D Transformation Pipeline article on MSDN.
Unfortunately, I haven't had any luck with that as well (same results), so any help would be highly appreciated, since I'm a bit stuck on this one.
Thank you.
Best Regards,
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将该线与 3D 空间中的前剪裁平面相交并截断该线,以便仅绘制可见的线段:
您有一条线
xo
,其中x
在剪裁平面前面,o
在剪裁平面后面。将此线与剪裁平面相交以生成点+
。您知道x
和o
中哪一个可见,因此从x
到+
画一条线。这样你就不会投影相机后面的点。
You need to intersect the line with the front clipping plane in 3d space and truncate the line so you only draw the line segment that's visible:
You've got a line
xo
wherex
in front of the clipping plane ando
behind it. Intersect this line with the clipping plane to generate the point+
. You know which ofx
ando
is visible so draw the line fromx
to+
.This way you're not projecting points which are behind the camera.