顶点数据的转换。鼠标拾取算法

Transformation of vertex data. Mouse picking algorithm

在我的程序中,我有一个 gizmo 可以移动场景中的任何对象。正如我所知,存储任何转换的常用方法是将该转换存储在该对象的模型矩阵中,并直接在着色器中执行任何转换。但也在我的程序中,我实现了一个经典的光线拾取算法,它只适用于真实的转换数据。射线检测与真实(转换)顶点位置的任何交点。解决这个冲突的常用方法是:

  1. 立即在 CPU 上乘以任何转换并存储转换后的数据。我认为这是一种清晰的方法,但它很昂贵:例如,我在 100 帧内将我的对象拖到屏幕上,每一帧我将移动的增量转换为矩阵并将整个数据乘以它。
  2. 将任何变换存储在矩阵中,直到开始鼠标拾取,然后快速将顶点乘以矩阵以准备拾取数据。这很花哨,但有办法优化它。

哪种方式效率更高。也许还有其他方法?

罗宾逊更新:

我想你误解了我的意思。或者我没有完全理解你。我有一个盒子和一个球体,我分别在 1,0,0 和 0,1,0 上通过 gizmo(我编辑它们的模型矩阵)移动它。他的模型矩阵现在不同了。在这里,我获得了光线拾取所需的数据 - 每个对象都有自己的位置。

然后我将整个场景转换为眼睛space(视图矩阵),然后剪辑space(投影矩阵)并渲染它。我的光线 return 从视口到世界 space(取消投影视图和投影矩阵)并且应该与实际场景交互。我的光线变换而不是场景!

我的问题是在渲染(或转换)之前如何与真实位置未知的对象进行交互?或者可能是我不在正确的轨道上,我应该以不同的方式来做——每一步乘以整个数据(这很昂贵,看看我的第一个问题)。

您使用技术上的光线拾取 "get x,y screen coordinates, transform them to NDC and set the z as anyone in the range [-1,1]; and finally transform them all back to world coordinates"。

当你想从视角(相机)到 "mouse coordinates" 的光线相交并且你想在 [=28= 上进行所有这些相交计算时,这很有用] 边。
请注意,即使屏幕上没有绘制任何内容,您也可以这样做,只需要鼠标坐标;好吧,再加上视口和当前的变换,但你在任何 glDrawxxx 命令之前就知道它们了。

接下来,问题是:你打算用那条射线或交点做什么?

您可能希望修改一些 属性(如颜色)或位置。正确的?
要修改多少个对象?如果它只是一堆,那么可以在 CPU 上修改数据以发送到 GPU。但是如果你有成千上万的对象然后考虑硬件加速的方式:保留它们的坐标但将新的转换矩阵和属性发送到 GPU 并让它完成艰苦的工作。

如果您担心某些对象保持原样但其他对象被修改,请记住您可以绘制共享矩阵和其他 uniform 的对象组s 与单个 glDrawxxx 调用。如果您有不同的组,请使用不同制服甚至不同着色器的多个 glDrawxxx 调用。