/// <summary> /// 利用层次包围盒计算颜色 /// </summary> /// <param name="r"></param> /// <param name="world"></param> /// <param name="depth"></param> /// <returns></returns> public static SColor Color(Ray r, BVH_node world, int depth) { AABB aBB = new AABB(); world.Bounding_box(0, 0, ref aBB); if (aBB.Hit(r, 1e-5)) { ShadeRec rec = new ShadeRec(); world.Hit(r, 1e-5, ref rec); if (rec.IsHit) { Ray scattered = new Ray(); Vector3D attenuation = new Vector3D(); SColor emitted = rec.Material.Emitted(rec);//光颜色 if (depth < 1 && rec.Material.Scatter(r, rec, ref attenuation, ref scattered)) { SColor colorTemp = Color(scattered, world, depth + 1); colorTemp = colorTemp * new SColor(attenuation); //有反射则将当前发光体发出的光和散射的颜色预以叠加 return(colorTemp + emitted); } else { //无反射则直接取发光射出的颜色 return(emitted); } } else { Vector3D unitDirection = Vector3D.UnitVector(r.Direction); double t = 0.5 * (unitDirection.Y + 1.0); return(new SColor((1.0 - t) + t * 0.5, (1.0 - t) + t * 0.7, (1.0 - t) + t * 1)); // return new SColor(1, 1, 1);//无背景色 } } else { Vector3D unitDirection = Vector3D.UnitVector(r.Direction); double t = 0.5 * (unitDirection.Y + 1.0); return(new SColor((1.0 - t) + t * 0.5, (1.0 - t) + t * 0.7, (1.0 - t) + t * 1)); // return new SColor(1, 0, 0);//无背景色 } }
/// <summary> /// 传入射线是否击中物体 /// </summary> /// <param name="r">射线</param> /// <param name="t_min">t可以取的最小值</param> /// <param name="rec">击中点信息</param> /// <returns>是否击中</returns> public virtual bool Hit(Ray r, double t_min, ref ShadeRec rec) { return(false); }
public abstract Vector3 Shade(ShadeRec sr);
public virtual Vector3 ShadeAreaLight(ShadeRec sr) { return(Shade(sr)); }
public abstract SColor GetColor(ShadeRec sr);