透视投影 - 如何投影“相机”后面的点?

发布于 2024-09-10 23:48:17 字数 960 浏览 13 评论 0原文

我正在用 Java 编写自己的软件光栅器,但遇到了一些麻烦...请看一下示例图像:

图像

这个示例只是在平面上绘制简单的方形网格。一切正常,直到我将相机移得足够近,使某些点移动到它后面。之后,它们不再正确投影,如​​您所见(垂直线 - 应该位于相机后面的点被投影到屏幕顶部)。

我的变换矩阵和向量与 DirectX 使用的矩阵和向量相同(用于投影的 PerspectiveFovLH,用于相机的 LookAtLH)。

我使用以下变换方法来投影 3D 点:

  1. 创建要变换的 3D 矢量。
  2. 向量乘以 ViewProjection 矩阵。
  3. 之后,使用以下方法将点转换为屏幕:

    // '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:

Image

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:

  1. 3D vector to be transformed is created.
  2. Vector is multiplied by ViewProjection matrix.
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

起风了 2024-09-17 23:48:17

您需要将该线与 3D 空间中的前剪裁平面相交并截断该线,以便仅绘制可见的线段:

             |
             |
             |
x------------+-----------o
             |
             |
             |   * - camera
             |
             |
             |
       clipping plane

您有一条线 xo,其中 x 在剪裁平面前面,o 在剪裁平面后面。将此线与剪裁平面相交以生成点 +。您知道 xo 中哪一个可见,因此从 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:

             |
             |
             |
x------------+-----------o
             |
             |
             |   * - camera
             |
             |
             |
       clipping plane

You've got a line xo where x in front of the clipping plane and o behind it. Intersect this line with the clipping plane to generate the point +. You know which of x and o is visible so draw the line from x to +.

This way you're not projecting points which are behind the camera.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文