Exemple #1
0
        public Color ColorAt(Ray r, int remaining)
        {
            List <Intersection> xs = IntersectWorld(r);
            Intersection        i  = Intersection.Hit(xs);

            if (i is null)
            {
                return(new Color(0, 0, 0));
            }
            else
            {
                Computations comps = Computations.PrepareComputations(i, r, xs);
                return(ShadeHit(comps, remaining));
            }
        }
Exemple #2
0
        public static double Schlick(Computations comps)
        {
            double cos = Tuple.Dot(comps.eyev, comps.normalv);

            if (comps.n1 > comps.n2)
            {
                double n     = comps.n1 / comps.n2;
                double sin2T = Math.Pow(n, 2.0) * (1.0 - Math.Pow(cos, 2.0));
                if (sin2T > 1.0)
                {
                    return(1.0);
                }
                double cosT = Math.Sqrt(1.0 - sin2T);
                cos = cosT;
            }
            double r0 = Math.Pow(((comps.n1 - comps.n2) / (comps.n1 + comps.n2)), 2.0);

            return(r0 + (1 - r0) * Math.Pow((1 - cos), 5.0));
        }
Exemple #3
0
        // Possibly change lighting call point -> overpoint to fix checkboard pattern
        public Color ShadeHit(Computations comps, int remaining)
        {
            bool  shadowed     = IsShadowedFromAllLights(comps.overPoint);
            Color surfaceColor = new Color(0, 0, 0);

            foreach (Light lt in Lights)
            {
                surfaceColor += comps.shape.Material.Lighting(comps.shape, lt, comps.overPoint, comps.eyev, comps.normalv, shadowed);
            }

            Color reflectedColor = ReflectedColor(comps, remaining);
            Color refractedColor = RefractedColor(comps, remaining);

            Material material = comps.shape.Material;

            if (material.Reflectivity > 0 && material.Transparency > 0)
            {
                double reflectance = Intersection.Schlick(comps);
                return(surfaceColor + reflectedColor * reflectance + refractedColor * (1.0 - reflectance));
            }
            return(surfaceColor + reflectedColor + refractedColor);
        }
Exemple #4
0
        public static Computations PrepareComputations(Intersection i, Ray r, List <Intersection> xs = null)
        {
            if (xs is null)
            {
                xs = new List <Intersection>();
                xs.Add(i);
            }
            Computations comps = new Computations();

            comps.t       = i.T;
            comps.shape   = i.S;
            comps.point   = r.Position(comps.t);
            comps.eyev    = -r.Direction;
            comps.normalv = comps.shape.NormalAt(comps.point, i);
            if (Tuple.Dot(comps.normalv, comps.eyev) < 0)
            {
                comps.inside  = true;
                comps.normalv = -comps.normalv;
            }
            else
            {
                comps.inside = false;
            }
            comps.reflectv   = Tuple.Reflect(r.Direction, comps.normalv);
            comps.overPoint  = comps.point + comps.normalv * Globals.EPSILON;
            comps.underPoint = comps.point - comps.normalv * Globals.EPSILON;

            List <Shape> containers = new List <Shape>();

            foreach (Intersection j in xs)
            {
                if (Globals.EqualityOfDouble(j.T, i.T) && j.S == i.S)
                {
                    if (containers.Count == 0)
                    {
                        comps.n1 = 1.0;
                    }
                    else
                    {
                        comps.n1 = containers[containers.Count - 1].Material.RefractiveIndex;
                    }
                }
                if (containers.Contains(j.S))
                {
                    containers.Remove(j.S);
                }
                else
                {
                    containers.Add(j.S);
                }
                if (Globals.EqualityOfDouble(j.T, i.T) && j.S == i.S)
                {
                    if (containers.Count == 0)
                    {
                        comps.n2 = 1.0;
                    }
                    else
                    {
                        comps.n2 = containers[containers.Count - 1].Material.RefractiveIndex;
                    }
                    break;
                }
            }
            return(comps);
        }