/// <summary> /// 光线追踪测试 /// </summary> /// <param name="ray"></param> /// <returns></returns> public override RayCastResult Intersection(Ray ray, float nowbest) { // 包围盒测试失败 { (bool happened, float mint) = BoundBox.Intersection(ray); if (!happened || mint > nowbest) // 未相交 或 当前最小解已不是最优 { return(null); } } RayCastResult result = BVH.Intersection(ray, float.MaxValue); if (result != null) { result.material = Material; if (result.internalPoint) { result.IOR = 1.0f; } else { result.IOR = Material.Refraction.IOR; } } return(result); }
public override RayCastResult Intersection(Ray ray, float nowbest) { if (ray.OriginObject == this) { return(null); } { (bool happened, Float mint) = BoundBox.Intersection(ray); if (!happened || mint > nowbest) // 未相交 或 当前最小解已不是最优 { return(null); } } Float u, v, t_tmp = 0; Vector3f pvec = Vector3f.Cross(ray.Direction, e2); // S1 Float det = Vector3f.Dot(e1, pvec); Float det_inv = 1.0f / det; Vector3f tvec = ray.Origin - v0; // S u = Vector3f.Dot(tvec, pvec) * det_inv; if (u < 0 || u > 1) { return(null); } Vector3f qvec = Vector3f.Cross(tvec, e1); // S2 v = Vector3f.Dot(ray.Direction, qvec) * det_inv; if (v < 0 || u + v > 1) { return(null); } t_tmp = Vector3f.Dot(e2, qvec) * det_inv; if (t_tmp < 0) { return(null); } RayCastResult result = new RayCastResult(); result.distance = t_tmp; result.obj = this; result.coords = ray.Origin + t_tmp * ray.Direction; result.uv = new Vector2f(u, v); result.normal = Tools.UVMerge(u, v, n0, n1, n2); result.internalPoint = (Vector3f.Dot(result.normal, ray.Direction) > 0); if (result.internalPoint) { result.normal = -result.normal; } return(result); }