我的射线盒相交算法效率有多低



我正在尝试着色器和光线盒之间碰撞的计算,这是通过以下方式完成的:

inline bool hitsCube(in Ray ray,            in Cube cube, 
out float tMin,        out float tMax,
out float3 signMin,    out float3 signMax)
{
float3 biggerThan0 = ray.odir > 0; // ray.odir = (1.0/ray.dir)
float3 lessThan0 = 1.0f - biggerThan0;

float3 tMinXYZ = cube.center + biggerThan0 * cube.minSize + lessThan0 * cube.maxSize;
float3 tMaxXZY = cube.center + biggerThan0 * cube.maxSize + lessThan0 * cube.minSize;

float3 rMinXYZ = (tMinXYZ - ray.origin) * ray.odir;
float3 rMaxXYZ = (tMaxXZY - ray.origin) * ray.odir;

float minV = max(rMinXYZ.x, max(rMinXYZ.y, rMinXYZ.z));
float maxV = min(rMaxXYZ.x, min(rMaxXYZ.y, rMaxXYZ.z));

tMin = minV;
tMax = maxV;

signMin = (rMinXYZ == minV) * lessThan0; // important calculation for another algorithm, but no context provided here
signMax = (rMaxXYZ == maxV) * lessThan0;

return maxV > minV * (minV + maxV >= 0); // last multiplication makes sure the origin of the ray is outside the cube
}

考虑到这个函数可以在hlsl着色器中调用很多次(对于一些像素,假设至少调用200/300次(:我的冲突逻辑实现效率低吗?

不是一个容易回答的"问题";,如果不知道周围发生的一切,很难说,但只是一些随机的想法:

a( 如果你真的有兴趣知道这在GPU上会是什么样子,我建议";移植";然后使用CUDA为现代GPU生成PTX和SASS(例如,用于图灵的sm75或用于安培的sm86(;然后比较SASS输出中的两种或三种变体。

b( ";将逻辑转换为乘法";可能会比你想象的要少——如果逻辑不是太复杂,有一个很好的改变,你可能会得到一些谓词,而且根本没有太多的扭曲分歧,所以可能不会太糟糕。唯一的方法是查看PTX和/或SASS输出,请参阅"a"。

c( tMinXYZ/tMaxXYZ的公式(IMHO(非常复杂:只需用最小/最大运算来表达它,这在GPU上非常便宜。还参见相应的章节";射线/盒相交";在光线追踪宝石2的书(免费下载(。数值上也更稳定btw.

d( re";滞后。。。我的逻辑效率低吗实际装配";效率;很少会产生如此巨大的影响;通常是"引人注目"的罪魁祸首;滞后";要么是内存停滞(很难猜测发生了什么(,要么是由于其他原因出现了严重错误(见下一个项目符号(。

e( 只是一种预感:我会检查一些方向分量为0的光线。在这种情况下,你除以0(从来都不是一个好主意(,特别是如果它乘以0.f(在你的情况下可能会发生(,你会得到NaN,因为";与NaN的比较总是错误的";您可能会以遍历逻辑总是向下而不是跳过的情况结束。与";效率;你的逻辑,但需要注意。好的解决办法是总是将0.f的每个射线.dir更改为1e-6f左右。

最新更新