3d - 如何计算光线行进中一定距离处的视锥半径(即像素的大小)?

标签 3d glsl antialiasing raytracing raycasting

我在 GLSL 中进行“光线行进距离场”(正确的行话:球体追踪)。为了在其之上实现圆锥行进(并且无论是否添加圆锥行进,也尽量减少光线行进步骤数),我需要估计任意给定距离处的射线圆锥的半径。

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

在第 0 步,该半径可以近似为诸如

float fInitialRadius = 1 / min(screenwidth, screenheight);

通过将起始半径应用于距离,可以在每一步以指数方式增加:

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

这工作正常,但仍然有工件。如果我使用 fInitialRadius*fInitialRadius(由于 640px 帧缓冲区的初始半径和单位宽度 View 平面为 1/640,导致数字更小),我会得到更少的伪影和更准确的结果。但这两种方法都不准确,第一种方法太急切(过早增加半径太多),后者太懒(增加半径太少太晚)。

增加 fNearLimit/给定距离处的圆锥半径的最准确因素很可能会考虑到我当前的视野,并且会根据视野是 45°、60°、90° 或...

TL;DR:我想知道给定距离处圆锥体半径的正确计算或最可接受的近似值是什么给定步骤 0 处的初始像素半径和视场角?

最佳答案

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

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

radius(distance) = distance * initialRadius / focalDistance

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

这里distance是光线到相机的距离,focalDistance是屏幕平面到相机的距离。

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

(或者也许更好,根本不使用距离。只需使用深度代替,即仅垂直于屏幕平面的矢量分量。这可能如果您已将场景旋转到相机框架中,则为您的 z 轴或 y 轴。)

关于3d - 如何计算光线行进中一定距离处的视锥半径(即像素的大小)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10492590/

相关文章:

graphics - 光线追踪折射看起来 "fake"

java - 如何使用 ARToolkit for Android 在 java(非 native c++)中加载 3d 模型

Java2D/Swing : Rendering a component with text anti aliasing to a BufferedImage

file - QCAR-sdk 和 MD2 文件

Matlab 冲浪图删除偏移量(非零)

c++ - 如何为 2D 和 3D 调整顶点着色器?

java - 尽管链接和验证成功,为什么着色器程序无法编译?

opengl-es - 在 OpenGL ES 2.0 中,如何从采样器读取相邻纹理像素?

image - Qml Image fillMode需要抗锯齿

ios - 在 iPad/iOS 上启用 4x MSAA 抗锯齿时出现伪影