原理:
通过一个简单的包围盒把物体包围起来,射线和场景中的物体求交之前,会先和这个包围盒进行求交,如果该射线没有碰到该包围盒,表明该直线一定不会和包围盒里的物体相交;如果该射线碰到该包围盒,那么再来计算射线是否和包围盒中的物体相交。
作用:
BVH可以使渲染器更加高效,值得注意的是盒子是可以重叠的。当然,盒子内也可以放其他的盒子,这样我们会得到一个树形结构。
怎样判断和盒子是否相交?
2D包围盒的边界是一条线,而3D包围盒的边界是一个面
射线可以看为是一个方程:P(t)=A+B*t
将这个公式实际应用
实现步骤:
1.修改Vector3D,Point3D中的代码,方便接下来的索引操作(对于索引器的操作:索引值为0返回x,值为1返回y,值为2返回z。)
public class Vector3D
{
public double[] data = new double[3];
public double this[int index]
{
get => data[index];
set => data[index] = value;
}
private double _x;
private double _y;
private double _z;
public double X
{
get => data[0];
set => data[0] = value;
}
public double Y
{
get => data[1];
set => data[1] = value;
}
public double Z
{
get => data[2];
set => data[2] = value;
}
//...省略其他代码...//
}
2.创建AABB包围盒的类
public class AABB
{
Vector3D _min;
Vector3D _max;
public AABB()
{
}
public AABB(Vector3D a,Vector3D b)
{
_min = a;
_max = b;
}
public Vector3D Min {
get => _min; set => _min = value; }
public Vector3D Max {
get => _max; set => _max = value; }
public bool hit(Ray r, double tmin,double tmax)
{
for (var a = 0; a < 3