光先追踪的加速方法就是引入层次结构数据结构,计算光线与层次结构的相交,从而加速光线与场景的求交。
AABB与Ray求交
- 在之前的部分我们说到了关于
OBB
与Ray
求交的计算jump,AABB算是比较特殊的OBB
,计算OBB
与Ray
的方法可能不在适用于AABB
与射线的求交计算,当然从原理上来说,这依旧是Slabs Method
。
计算
前置判断
- 考虑射线起点在盒子里面的情况
- 考虑射线和盒子某个面平行的时候
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| vec3 begin; vec3 u; std::array<vec3,3> normals; vec3 min,max;
float del = 1e-6; for(auto i = 0;i < 3;i++) { if(u[i] < del) { if(begin[i] < min[i] || begin[i] > max[i]) return false; } } return true;
|
计算每个方向上对应的slab
与射线的相交情况
- \(P = P_0 + t \dots \vec{d}\)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| float del = 1e-6; vec3 begin; vec3 u; std::array<vec3,3> normals; vec3 min,max;
double tMin = DBL_MIN,tMax = DBL_MAX;
for(auto i = 0;i < 3;i++) { const dis = 1.0 / u[i]; float t_min; float t_max; if(dis >= del) { t_max = = (max[i] - begin[i]) * dis; t_min = = (min[i] - begin[i]) * dis; } else { t_max = = (min[i] - begin[i]) * dis; t_min = = (max[i] - begin[i]) * dis; }
if(t_max < t_min) { swap(t_max,t_min); } if(tMin > t_min) { tMin = t_min; } if(tMax < t_max) { tMax = t_max; } if(tMin > tMax) return false; }
return ture;
|
判断