public Vector4 ShadeHit(Computations comp, int remainingReflections = 0) { var surfaceColor = Lights.Select(light => comp.Object.Material.ComputeColor( light, comp.Object, comp.OverPoint, comp.EyeV, comp.NormalV, inShadow: IsShadowed(light, comp.FarOverPoint))) .Aggregate(VColor.Black, (finalColor, color) => finalColor + color); var reflectedColor = ComputeReflectedColor(comp, remainingReflections); var refractedColor = ComputeRefractedColor(comp, remainingReflections); var material = comp.Object.Material; if (material.Reflective > 0 && material.Transparency > 0) { var reflectance = comp.GetSchlickReflectance(); return(surfaceColor + reflectedColor * reflectance + refractedColor * (1 - reflectance)); } else { return(surfaceColor + reflectedColor + refractedColor); } }
public Vector4 ComputeReflectedColor(Computations comps, int remainingReflections = 0) { if (comps.Object.Material.Reflective.IsZero() || remainingReflections == 0) { return(VColor.Black); } var reflectRay = CreateRay(comps.OverPoint, comps.ReflectV); var color = ComputeColor(reflectRay, remainingReflections - 1); return(color * comps.Object.Material.Reflective); }
public Vector4 ComputeColor(Ray ray, int remainingReflections = 0) { var xs = Intersect(ray); var hit = xs.TryGetHit(); if (hit == null) { return(VColor.Black); } var comp = Computations.Prepare(hit, ray, xs); return(ShadeHit(comp, remainingReflections)); }
public Vector4 ComputeRefractedColor(Computations comps, int remainingReflections) { if (comps.Object.Material.Transparency.IsZero() || remainingReflections == 0) { return(VColor.Black); } var nRatio = comps.N1 / comps.N2; var cosI = Dot(comps.EyeV, comps.NormalV); var sinT2 = nRatio * nRatio * (1 - cosI * cosI); if (sinT2 > 1) { return(VColor.Black); } var cosT = Sqrt(1 - sinT2); var direction = comps.NormalV * (nRatio * cosI - cosT) - comps.EyeV * nRatio; var refractRay = new Ray(comps.UnderPoint, direction); return(ComputeColor(refractRay, remainingReflections - 1) * comps.Object.Material.Transparency); }