如何计算射线追踪中一定距离的视锥半径(即像素的大小)?

时间:2012-05-08 04:33:39

标签: 3d glsl antialiasing raytracing raycasting

我是GLSL中的“射线追踪距离场”(正确的术语:球体追踪)。为了实现它上面的锥形行进(并且无论是否添加锥形行进,最小化射线追踪步骤的数量),我需要估计任何给定距离处的射线锥的半径。

回想一下光线追踪距离场,当到物体的距离小于阈值时,通常在名为nearLimit或epsilon的代码中记录“命中”。如果我们随着行进距离以指数方式增加该阈值,则该阈值可以看作等同于光束半径 - 这样,我们不会将直线细线射入太空,而是根据透视投影扩展锥体。这更准确地涵盖了捕捉“正确的”远处物体(此时让我们忽略混合材料和过滤距离t处视锥中所有相交物体的法线的问题...)。

在步骤0,此半径可以通过诸如

之类的东西来近似
float fInitialRadius = 1 / min(screenwidth, screenheight);

然后可以通过将起始半径应用于距离来指数增加每一步:

fNearLimit = fTotalDist * fInitialRadius;  // after each raymarching step

这样可行,但仍有工件。如果我使用fInitialRadius * fInitialRadius(由于640px帧缓冲区的初始半径以及单位宽度视图平面为1/640导致数字较小),我得到的伪像更少,结果更准确。但是这两种方法都是不准确的,第一种方法太急切了(过早地增加半径太多),后者太懒了(太半时太少增加半径)。

在给定距离增加fNearLimit /锥形半径的最准确因素必须考虑到我当前的视野,并且会根据视场是45°还是60°或90°或...

TL; DR :我想知道在步骤0给定初始像素半径的情况下,给定距离处的锥半径的正确计算或最可接受的近似值视角?

1 个答案:

答案 0 :(得分:3)

圆锥的半径与其尖端的距离成线性对应。 (否则它不是锥形!)

因此,如果你的圆锥与屏幕平面相交时有initialRadius,那么稍后:

radius(distance) = distance * initialRadius / focalDistance

您必须在每一步重新计算该值,因为每一步都会占用不同的距离。

此处distance是光线距相机的距离,focalDistance是屏幕平面与相机的距离。

(对于不在屏幕中心的像素,而不是focalDistance,使用屏幕平面上像素距离相机的距离可能更准确。)

(或者更好,根本不要使用距离。只需使用 depths ,即只使用垂直于屏幕平面的矢量分量。如果已将场景旋转到相机框架中,则为z轴或y轴。)