【问题标题】:The most effective way of computing distance to sphere in CUDA?在CUDA中计算球体距离的最有效方法?
【发布时间】:2019-05-01 00:21:59
【问题描述】:

我在 CUDA 中对有符号距离场进行 raymarching,我正在渲染的场景包含数千个球体(球体的位置存储在设备缓冲区中,因此我的 SDF 函数会遍历 所有 球体每个像素)。

目前,我计算到球体表面的距离为:

sqrtf( dot( pos - sphere_center, pos - sphere_center ) ) - sphere_radius

使用sqrt() 函数,我的场景渲染大约需要 250 毫秒。然而,当我移除对sqrt() 的调用并只留下dot( pos - sphere_center, pos - sphere_center ) - sphere_radius 时,渲染时间下降到17 毫秒(并渲染黑色图像)。

sqrt() 函数似乎是瓶颈,所以我想问一下是否有办法可以改善我的渲染时间(通过使用不使用平方根的不同公式或不同的渲染方法)?

我已经在使用-use-fast-math

编辑:我尝试了Nico Schertler 建议的公式,但它在我的渲染器中不起作用。 Link to M(n)WE on Shadertoy.

【问题讨论】:

  • 如果只需要零水平集,可以使用dot( pos - sphere_center, pos - sphere_center ) - sphere_radius * sphere_radius字段。
  • 如果currDst 不是实际距离,@wlcezar currPt += rd * currDst; 显然是行不通的……但即使是这样,这也可能无法达到你想要的效果……除非你的光线击中正好是球心,这里你沿射线移动的距离不是沿射线测量的距离……
  • 以防万一:如果您只想与球体相交,则无需使用距离场。球体和射线的交集可以直接计算出来……
  • 也许您可以将平方距离的使用“传播”到其余的计算中。至少你可以这样做:min(squared_distance_to_closest_sphere, distance_to_the_closest_object_in_the_rest_of_the_scene^2) - 对吧?
  • --use-fast-mathsqrt() AFAIK 上有no effect。如果您使用sqrt()(即不是sqrtf()),如果您可以切换到例如,您可能会获得一些好处。 __fsqrt_rn()

标签: math optimization cuda render


【解决方案1】:

(将我的评论变成答案,因为它似乎对 OP 有效)

您正在感受必须计算 sqrt() 的痛苦。我很同情...如果你能,嗯,这样做,那就太好了。那么,是什么阻止了你?毕竟,到球体的平方距离是一个从 $R^+$ 到 $R^+$ 的单调函数——见鬼,它实际上是一个凸双射!问题是你有来自其他地方的非平方距离,你计算:

min(sqrt(square_distance_to_the_closest_sphere), 
    distance_to_the_closest_object_in_the_rest_of_the_scene)

所以让我们换一种方式来做:与其取球体的平方距离的平方根,不如取 other 距离的平方:

min(square_distance_to_the_closest_sphere,
    distance_to_the_closest_object_in_the_rest_of_the_scene^2)

由于平方函数的单调性,这与未平方 min() 计算的选择相同。从这里开始,尝试在您的程序中进一步传播平方距离的使用,尽可能避免取根,甚至可能是一路。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 2017-11-24
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多