在 CUDA 中,如何在内核函数中将屏幕空间坐标转换为世界空间坐标

Posted

技术标签:

【中文标题】在 CUDA 中,如何在内核函数中将屏幕空间坐标转换为世界空间坐标【英文标题】:In CUDA, how to translate screen space coordinate to world space coordinate in the Kernel Function 【发布时间】:2012-05-25 02:45:16 【问题描述】:

在这里,我尝试将光线投射添加到真实的 3D 场景中。众所周知,在光线投射中,为了投射光线,我们需要获取光线的方向。射线中的第一个点是射线的起点,我可以从 glLookAt 获得。射线中的第二个点是屏幕中的每个点。在原来的CUDA ray-casting SDK中,通过以下代码在Kernel Function中获取屏幕点:

uint x = blockIdx.x*blockDim.x + threadIdx.x;
uint y = blockIdx.y*blockDim.y + threadIdx.y;

(x,y) 是屏幕空间坐标吗?所以现在我需要将 (x, y) 翻译成世界空间坐标。一个好人告诉我使用 gluUnProject 来完成这项工作。好想法!但是我不能在 CUDA 内核中调用 OpenGL 函数。

也许我可以使用可逆矩阵进行翻译。但我不确定正确的方法。有没有人可以给我一个关于如何在 CUDA 内核函数中将屏幕坐标转换为世界坐标的提示?

【问题讨论】:

您需要什么帮助并不是那么明显。是转换的数学,还是数学的 CUDA 实现或什么?或许你可以先写一段执行转换的主机代码并确认它是正确的,然后看看如何将计算映射到 CUDA 执行模型中的问题。 您可以查看gluUnproject() 的源代码并在CUDA 代码中实现它。这个问题与 CUDA 完全正交——你需要的只是数学,然后是每个线程执行的 C 代码。 【参考方案1】:

我的解决方案是这样的:在CUDA内核中,它是这样获取屏幕坐标的:

uint x = blockIdx.x*blockDim.x + threadIdx.x;
uint y = blockIdx.y*blockDim.y + threadIdx.y;

其实它代表另一个坐标空间,屏幕垂直于Z轴。从 gluPerspective 中,我们也可以得到屏幕到视图位置的距离。因此,当我们知道视图位置时,我们可以计算屏幕的 Z 坐标。所以屏幕中每个点的坐标在这个特定的坐标空间下都是(x,y,z)。

在这个特定的坐标空间中,视图方向平行于 Z 轴。此外,我们知道世界空间中的视图方向。所以我们只需要计算将 Z 轴对齐的视图方向(特别是上面的坐标空间)转换为真实视图方向(在世界空间中)的转换矩阵。

然后我们使用这个矩阵将屏幕中的每个点 (x,y,z) 转换为一个世界空间。这就是世界空间坐标。

我现在正在尝试实现这个,我觉得这个想法还可以,实现后我会接受这个答案。

【讨论】:

以上是关于在 CUDA 中,如何在内核函数中将屏幕空间坐标转换为世界空间坐标的主要内容,如果未能解决你的问题,请参考以下文章

23 网络数据在内核中流转

设备内存空间中的 cuda 程序内核代码

在Windows内核地址空间中将虚拟地址转换为物理地址

[转]gluProject 和 gluUnproject 的详解

Unity UI跟随3D物体,世界坐标转UI坐标

我应该如何从屏幕空间坐标转换为 WinForms PictureBox 中的图像空间坐标?