public Color RefractedColor(Computation comps, int remaining = 5) { if (remaining <= 0) { return(Color.Black); } if (comps.Object.Material.Transparency == 0) { return(Color.Black); } var nRatio = comps.N1 / comps.N2; var cosI = PointType.DotProduct(comps.EyeV, comps.NormalV); var sin2t = nRatio * nRatio * (1 - cosI * cosI); if (sin2t > 1) { return(Color.Black); } var cosT = Math.Sqrt(1 - sin2t); var direction = comps.NormalV * (nRatio * cosI - cosT) - comps.EyeV * nRatio; var refractRay = new Ray(comps.UnderPoint, direction); var color = ColorAt(refractRay, remaining - 1) * comps.Object.Material.Transparency; return(color); }
public static Computation PrepareComputations(Intersection i, Ray r, Intersection[] xs = null) { var c = new Computation { T = i.T, Object = i.Object }; c.Point = transform.Position(r, c.T); c.EyeV = -r.Direction; c.NormalV = (c.Object as Shape).NormalAt(c.Point, i); if (PointType.DotProduct(c.NormalV, c.EyeV) < 0) { c.Inside = true; c.NormalV = -c.NormalV; } else { c.Inside = false; } c.OverPoint = c.Point + c.NormalV * EPSILON; c.UnderPoint = c.Point - c.NormalV * EPSILON; c.RelflectV = Light.Reflect(r.Direction, c.NormalV); if (xs == null) { xs = new Intersection[] { i } } ; GetRefractions(i, xs, out var n1, out var n2); c.N1 = n1; c.N2 = n2; return(c); }
public static PointType Reflect(PointType vector, PointType normal) => vector - normal * 2 * PointType.DotProduct(vector, normal);