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