Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 射线三角形交点_Algorithm_Graphics_Geometry_Rendering - Fatal编程技术网

Algorithm 射线三角形交点

Algorithm 射线三角形交点,algorithm,graphics,geometry,rendering,Algorithm,Graphics,Geometry,Rendering,我看到Moller和Trumbore经常被推荐 问题是,我不介意预计算和存储任何数量的数据,只要它能加速交叉口 所以我的问题是,不考虑内存,做光线三角形相交的最快方法是什么 编辑:我不会移动三角形,即它是一个静态场景。一个建议是实现八叉树(http://en.wikipedia.org/wiki/Octree)将3D空间划分为非常精细的块的算法。分区越精细,所需内存就越多,但树的精确度就越高 您仍然需要检查光线/三角形交点,但其想法是,树可以告诉您何时可以跳过光线/三角形交点,因为光线保证不会击

我看到Moller和Trumbore经常被推荐

问题是,我不介意预计算和存储任何数量的数据,只要它能加速交叉口

所以我的问题是,不考虑内存,做光线三角形相交的最快方法是什么


编辑:我不会移动三角形,即它是一个静态场景。

一个建议是实现八叉树(http://en.wikipedia.org/wiki/Octree)将3D空间划分为非常精细的块的算法。分区越精细,所需内存就越多,但树的精确度就越高

您仍然需要检查光线/三角形交点,但其想法是,树可以告诉您何时可以跳过光线/三角形交点,因为光线保证不会击中三角形


然而,如果你开始移动你的三角形,你需要更新八叉树,然后我不确定它会为你节省什么

正如其他人所提到的,加速的最有效方法是使用加速结构来减少所需的光线三角形交点的数量。也就是说,你仍然希望你的光线三角形交点是快的。如果您乐于预计算,可以尝试以下方法:

将光线线和三角形边转换为。这允许您确定光线线是否以每边6倍/相加的速度通过三角形。您仍然需要将光线的起点和终点与三角形平面进行比较(每个点有4个乘法/加法),以确保它实际命中三角形

最坏情况下的运行时费用总计为26乘/加。另外,请注意,每个光线/边组合只需计算一次光线/边符号,因此,如果要计算网格,可以使用每个边计算两次


此外,这些数字假设一切都是在齐次坐标系下进行的。通过提前规范化,您可以减少一些乘法运算的次数。

找到Dan Sunday的这篇文章:

根据第一次拒绝测试之前的操作计数,该算法的效率略低于MT(Möller&Trumbore)算法[…]。然而,MT算法使用两个叉积,而我们的算法只使用一个叉积,我们使用的一个叉积计算三角形平面的法向量,这是计算线参数rI所需要的。但是,当为场景中的所有三角形预计算并存储法向量时(通常情况下),我们的算法根本不需要计算这个叉积。但是,在这种情况下,MT算法仍然会计算两个叉积,并且效率低于我们的算法

我已经做了很多基准测试,我可以自信地说,最快的(公布的)方法是哈维尔和赫罗特发明并在他们的论文中介绍的方法。即使不使用SSE,它的速度也是Möller和Trumbore算法的两倍

Havel Herout的My C实现:

typedef结构{
vec3 n0;浮点d0;
vec3 n1;浮动d1;
vec3 n2;浮球d2;
}isect_hh_数据;
无效的
isect_hh_pre(vec3 v0、vec3 v1、vec3 v2、isect_hh_数据*D){
vec3 e1=v3_sub(v1,v0);
vec3 e2=v3_sub(v2,v0);
D->n0=v3_交叉(e1,e2);
D->d0=v3_点(D->n0,v0);
浮点数=1/v3点(D->n0,D->n0);
D->n1=v3\u刻度(v3\u交叉(e2,D->n0),inv\u denom);
D->d1=-v3_点(D->n1,v0);
D->n2=v3_刻度(v3_交叉(D->n0,e1),inv_刻度);
D->d2=-v3_点(D->n2,v0);
}
内联布尔
isect_hh(vec3 o,vec3 d,float*t,vec2*uv,isect_hh_data*d){
浮点数=v3_点(D->n0,D);
浮点数=D->d0-v3_点(o,D->n0);
vec3-wr=v3-u-add(v3-u标度(o,det),v3-u标度(d,det));
uv->x=v3_点(wr,D->n1)+det*D->d1;
uv->y=v3_点(wr,D->n2)+det*D->d2;
浮动tmpdet0=det-uv->x-uv->y;
int pdet0=((int_或浮点数)tmpdet0);
int pdetu=((int_或浮点数)uv->x);
int pdetv=((int_或_float)uv->y);
pdet0=pdet0^pdetu;
pdet0=pdet0 |(pdetu^pdetv);
如果(pdet0和0x8000000)
返回false;
浮动rdet=1/det;
uv->x*=rdet;
uv->y*=rdet;
*t=dett*rdet;

return*t>=ISECT_NEAR&&t谢谢!三角形不会移动。八叉树的问题是,也许我误解了,一片叶子中可能有几个三角形,对吧?在这种情况下,我仍然需要一个快速交集例程。谢谢。通过任何更改,您不知道示例代码的位置吗?顺便问一下,您使用哪种加速结构推荐以及原因?几年前,最先进的技术使用了高度优化的k-d树。特别是对于静态场景,这可能是你最好的选择。重新采样代码,我在谷歌发现了一些东西。没有保证——这篇论文看起来很旧,但它的解释似乎足够清楚,它的基准测试将普吕克代码的显著优势归因于它。我经常使用Moller和Trumbore的快速最小存储光线/三角形相交。但这是我第一次了解这篇论文。我认为对于很多光线和三角形,除了空间分割技术,可以同时考虑并行方法。我正在做OpenCL实现,但我不知道是否有人已经这样做了。你听说了吗?@squid你可以看看LuxRender的Luxray