在CUDA中计算到球面距离的最有效方法是什么?

时间:2019-05-01 00:21:59

标签: math optimization cuda render

我正在CUDA中对签名的距离字段进行光线影射,并且我渲染的场景包含数千个球体(球体的位置存储在设备缓冲区中,因此我的SDF函数通过 all 进行迭代)每个像素)。

目前,我正在计算到球面的距离:

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

使用sqrt()函数,渲染场景大约需要250毫秒。但是,当我删除对sqrt()的调用并仅保留dot( pos - sphere_center, pos - sphere_center ) - sphere_radius时,渲染时间降至17ms(并渲染黑色图像)。

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

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

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

1 个答案:

答案 0 :(得分:4)

(将我的评论作为答案,因为它似乎对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()计算选择相同。从这里开始,尝试在您的程序中进一步传播平方距离的使用,避免尽可能地扎根,甚至可能一直扎根。