我看到通常建议使用moller和trumbore的快速最小存储射线/三角形相交。
事实是,我不介意预先计算和存储任何数量的数据,只要它加快了交叉点。
所以我的问题是,不关心记忆,做射线三角形交集的最快方法是什么?
编辑:我不会移动三角形,即这是一个静态场景。
正如其他人所提到的,加快事物的最有效方法是使用加速结构来减少所需的射线三角形交集的数量。也就是说,您仍然希望射线三角形的交叉点快速。如果您很乐意预先计算内容,则可以尝试以下内容:
将射线线和三角形边缘转换为plücker坐标。这使您可以确定射线线是否通过6个乘/添加每个边缘的三角形通过三角形。您仍然需要将射线的起点和终点与三角平面(以4个倍数/每个点添加)进行比较,以确保它实际上击中了三角形。
最坏的情况下运行时费用为26倍数/添加总数。另外,请注意,您只需要每次射线/边缘组合一次计算射线/边缘符号,因此,如果您要评估网格,则可以两次使用每个边缘评估。
另外,这些数字认为一切都在均匀的坐标中完成。您可能可以通过提前标准化事物来减少某些乘法的数量。
我已经完成了基准的 lot ,我可以自信地说最快(已发布)方法是由Havel和Herout,并在他们的论文中介绍了更快的Ray-Triangle交叉点(使用SSE4)。即使在不使用SSE 的情况下,它的速度大约是Möller和Trumbore算法的两倍。
我的C实施Havel-Herout:
typedef struct {
vec3 n0; float d0;
vec3 n1; float d1;
vec3 n2; float d2;
} isect_hh_data;
void
isect_hh_pre(vec3 v0, vec3 v1, vec3 v2, isect_hh_data *D) {
vec3 e1 = v3_sub(v1, v0);
vec3 e2 = v3_sub(v2, v0);
D->n0 = v3_cross(e1, e2);
D->d0 = v3_dot(D->n0, v0);
float inv_denom = 1 / v3_dot(D->n0, D->n0);
D->n1 = v3_scale(v3_cross(e2, D->n0), inv_denom);
D->d1 = -v3_dot(D->n1, v0);
D->n2 = v3_scale(v3_cross(D->n0, e1), inv_denom);
D->d2 = -v3_dot(D->n2, v0);
}
inline bool
isect_hh(vec3 o, vec3 d, float *t, vec2 *uv, isect_hh_data *D) {
float det = v3_dot(D->n0, d);
float dett = D->d0 - v3_dot(o, D->n0);
vec3 wr = v3_add(v3_scale(o, det), v3_scale(d, dett));
uv->x = v3_dot(wr, D->n1) + det * D->d1;
uv->y = v3_dot(wr, D->n2) + det * D->d2;
float tmpdet0 = det - uv->x - uv->y;
int pdet0 = ((int_or_float)tmpdet0).i;
int pdetu = ((int_or_float)uv->x).i;
int pdetv = ((int_or_float)uv->y).i;
pdet0 = pdet0 ^ pdetu;
pdet0 = pdet0 | (pdetu ^ pdetv);
if (pdet0 & 0x80000000)
return false;
float rdet = 1 / det;
uv->x *= rdet;
uv->y *= rdet;
*t = dett * rdet;
return *t >= ISECT_NEAR && *t <= ISECT_FAR;
}
一个建议可能是实现OCTREE(http://en.wikipedia.org/wiki/octree)算法,以将3D空间划分为非常细的块。分区越细,所需的内存越多,但是树的准确性越好。
您仍然需要检查射线/三角形的交叉点,但是想法是,这棵树可以告诉您何时可以跳过射线/三角形交叉点,因为保证射线不会击中三角形。
但是,如果您开始移动三角形,则需要更新OCTREE,然后我不确定它会为您节省任何东西。
Dan Sunday:
找到了这篇文章基于对第一个拒绝测试的操作计数的计数,该算法的效率低一些,而不是MT(Möller&amp; trumbore)算法的效率,[...]。但是,MT算法使用两种跨产品,而我们的算法仅使用一种,而我们使用的算法计算了三角平面的正常向量,这是计算线参数 ri 所需的。但是,当对场景中的所有三角形(通常是这种情况)中对正常向量进行了预先计算并存储时,我们的算法根本不必计算此跨产品。但是,在这种情况下,MT算法仍将计算两种跨产品,并且效率不如我们的算法。
http://geomalgorithms.com/a06-_intersect-2.html