private Illuminance ShootRay(Ray Ray, int loop) { if (loop == 0) { return(Illuminance.Black); } Shape shape = null; var distance = double.PositiveInfinity; foreach (var s in shapes) { var t = s.Intersection(Ray); if (!t.IsPositive()) { continue; } if (distance < t) { continue; } shape = s; distance = t; } if (shape == null) { return(sky); } var result = new Illuminance(); var Intersection = Ray.Away(distance); var Normal = shape.NormalVector(Intersection); foreach (var l in lightes) { Illuminance light = l.Spotlight(this, shape, Intersection, Ray, Normal); result = result.Add(light); } if (!shape.Material.FSRC.IsDark()) //鏡 { var v = Ray.Direction.Reversed(); var d = Normal.Dot(v); if (d > 0.0) { var r = Normal.Mul(2 * v.Dot(Normal)).Sub(v); var ray = new Ray(Intersection.Add(r.Mul(MathHelper.Epsilon)), r); result = result.Add(ShootRay(ray, loop - 1)); } } return(result); }
public override Illuminance Spotlight(World World, Shape Shape, Vector3 Spot, Ray Ray, Vector3 Normal) { Vector3 Incident = Point.Sub(Spot); double Dl = Incident.Norm() - MathHelper.Epsilon; Incident.Normalize(); Ray shadow = new Ray(Spot.Add(Incident.Mul(MathHelper.Epsilon)), Incident); foreach (var s in World.Shapes) { var t = s.Intersection(shadow); if (t < Dl) { return(Illuminance.Black); } } double d = Normal.Dot(Incident).ToRate(); Illuminance ld = Shape.Material.DRC.Mul(Illuminance.Mul(d)); if (d > 0.0 && (!Shape.Material.SRC.IsDark()) && Shape.Material.Shininess > 0.0) { Vector3 r = Normal.Mul(d * 2).Sub(Incident).Normalized(); Vector3 v = Ray.Direction.Reversed(); ld = ld.Add(Illuminance.Mul(Shape.Material.SRC.Mul(Math.Pow(r.Dot(v).ToRate(), Shape.Material.Shininess)))); } return(ld); }