示例#1
0
        //public Computation(float t, RayObject rayObject,
        //                    Point point, Vector3 eyeV,
        //                    Vector3 normalV, bool inside,
        //                    Vector3 reflectV, float n1,
        //                    float n2)
        //{
        //    this.t = t;
        //    this.rayObject = rayObject;
        //    this.point = point;
        //    this.eyeV = eyeV;
        //    this.normalV = normalV;
        //    this.inside = inside;

        //    overPoint = point + normalV * Utilities.shadowPointEpsilon;

        //    this.reflectV = reflectV;

        //    this.n1 = n1;
        //    this.n2 = n2;

        //}

        public Computation(Intersection i, Ray r, List <Intersection> xs = null)
        {
            this.t         = i.t;
            this.rayObject = i.rayObject;
            this.point     = r.GetPointPosition(i.t);
            this.eyeV      = -r.direction;
            this.normalV   = rayObject.GetNormal(point);

            // Checks if eye vector and normal are pointing in the same direction
            // if dot product is less than zero that point in the same direction.
            if (Vector3.Dot(eyeV, normalV) < 0)
            {
                inside  = true;
                normalV = -normalV;
            }
            else
            {
                inside = false;
            }


            // If a List<Intersection> parameter is not passed into the method
            // create one using i as the only intersection in the list
            if (xs == null)
            {
                xs = new List <Intersection>()
                {
                    i
                }
            }
            ;

            // Transparency Intersections algorithm
            List <RayObject> containers = new List <RayObject>();

            foreach (Intersection intersect in xs)
            {
                // n1
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        this.n1 = 1.0f;
                    }
                    else
                    {
                        this.n1 = containers.Last <RayObject>().material.RefractIndex;
                    }
                }

                if (containers.Contains(intersect.rayObject))
                {
                    containers.Remove(intersect.rayObject);
                    //Console.WriteLine("Object Removed: " + intersect.rayObject.ToString());
                }
                else
                {
                    containers.Add(intersect.rayObject);
                    //Console.WriteLine("Object Added: " + intersect.rayObject.ToString());
                }
                //Console.WriteLine("List Lenght: " + containers.Count);

                // n2
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        this.n2 = 1.0f;
                    }
                    else
                    {
                        this.n2 = containers[containers.Count - 1].material.RefractIndex;
                    }
                    break;
                }
            }

            this.reflectV   = Vector3.Reflection(r.direction, this.normalV);
            this.overPoint  = point + normalV * Utilities.OVER_POINT_EPSILON;
            this.underPoint = point - normalV * Utilities.UNDER_POINT_EPSILON;
        }
        /// <summary>
        /// Given an Intersection and a Ray
        /// evaluates for eye vector, normal vector, insection point,
        /// and if ray is inside of object.
        /// This is the same as calling the Computation class constructor with Intersection and Ray parameter
        /// </summary>
        /// <param name="i"></param>
        /// <param name="r"></param>
        public static Computation PrepareComputations(Intersection i, Ray r, List <Intersection> xs = null)
        {
            Computation comp = new Computation();

            comp.t         = i.t;
            comp.rayObject = i.rayObject;
            comp.point     = r.GetPointPosition(i.t);
            comp.eyeV      = -r.direction;
            comp.normalV   = comp.rayObject.GetNormal(comp.point);

            // Checks if eye vector and normal are pointing in the same direction
            // if dot product is less than zero that point in the same direction
            if (Vector3.Dot(comp.eyeV, comp.normalV) < 0)
            {
                comp.inside  = true;
                comp.normalV = -comp.normalV;
            }
            else
            {
                comp.inside = false;
            }


            if (xs == null)
            {
                xs = new List <Intersection>()
                {
                    i
                }
            }
            ;

            // Transparency Intersections algorithm
            List <RayObject> containers = new List <RayObject>();

            foreach (Intersection intersect in xs)
            {
                // n1
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        comp.n1 = 1.0f;
                    }
                    else
                    {
                        comp.n1 = containers.Last <RayObject>().material.RefractIndex;
                    }
                }

                if (containers.Contains(intersect.rayObject))
                {
                    containers.Remove(intersect.rayObject);
                    //Console.WriteLine("Object Removed: " + intersect.rayObject.ToString());
                }
                else
                {
                    containers.Add(intersect.rayObject);
                    //Console.WriteLine("Object Added: " + intersect.rayObject.ToString());
                }
                //Console.WriteLine("List Lenght: " + containers.Count);

                // n2
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        comp.n2 = 1.0f;
                    }
                    else
                    {
                        comp.n2 = containers[containers.Count - 1].material.RefractIndex;
                    }
                    break;
                }
            }

            comp.reflectV   = Vector3.Reflection(r.direction, comp.normalV);
            comp.overPoint  = comp.point + comp.normalV * Utilities.OVER_POINT_EPSILON;
            comp.underPoint = comp.point - comp.normalV * Utilities.UNDER_POINT_EPSILON;

            return(comp);
        }
    }
示例#3
0
        /// <summary>
        /// Old Lighting method. Uses bool type for determining if in shadow.
        /// Doesn't adjust shadow darkness based on transparency of object blocking light
        /// Legacy method. Will Remove eventually.
        /// </summary>
        /// <param name="material"></param>
        /// <param name="rayObject"></param>
        /// <param name="light"></param>
        /// <param name="point"></param>
        /// <param name="eyeV"></param>
        /// <param name="normalV"></param>
        /// <param name="inShadow"></param>
        /// <returns></returns>
        public Color Lighting(Material material, RayObject rayObject, Light light, Point point,
                              Vector3 eyeV, Vector3 normalV, bool inShadow) // LEGACY // CONSIDER removing material from parameter list. Already getting data from self. Also CONSIDER moving RayObject call.
        {
            Color ambient  = Color.White;
            Color diffuse  = Color.White;
            Color specular = Color.White;

            Color effect_color;

            if (pattern != null)
            {
                // Combines surface pattern color with light's color/intensity if a pattern exist
                effect_color = pattern.PatternAtObject(rayObject, point) * light.Intensity;
            }
            else
            {
                // Combines surface color with light's color/intensity
                effect_color = material.mColor * light.Intensity;
            }


            // find the direction to the light source
            Vector3 lightV = (light.Position - point).Normalized();

            // Compute the ambient contribution
            ambient = effect_color * material.Ambient;

            // If in shadow just return the ambient color AND
            // if object that the ray hits on the way to the light source is completely non-transparent
            // skip diffuse and specular calculations return ambient color.
            if (inShadow)
            {
                return(ambient);
            }

            // lighDotNormal represents the cosine of the angle between the
            // light vector and the normal vector. A negative number means the
            // light is on the other side of the surface.
            float lighDotNormal = Vector3.Dot(lightV, normalV);

            if (lighDotNormal < 0)
            {
                diffuse  = Color.Black;
                specular = Color.Black;
            }
            else
            {
                // Compute the diffuse contribution
                diffuse = effect_color * material.Diffuse * lighDotNormal;

                // reflectDotEye represents the cosine of the angle between the
                // reflection vector and the eye vector. A negative number means the
                // light reflects away from the eye.
                Vector3 reflectV      = Vector3.Reflection(-lightV, normalV);
                float   reflectDotEye = Vector3.Dot(reflectV, eyeV);

                // if reflection is away from eye
                if (reflectDotEye <= 0)
                {
                    specular = Color.Black;
                }
                else
                {
                    // compute the specular contribution
                    float factor = (float)Math.Pow(reflectDotEye, material.Shininess);
                    specular = light.Intensity * material.Specular * factor;
                }
            }

            /*
             * Console.WriteLine("Ambient: " + ambient.ToString());
             * Console.WriteLine("Diffuse: " + diffuse.ToString());
             * Console.WriteLine("Specular: " + specular.ToString());
             */

            // Add the three contributions together to get the final shading
            return(ambient + diffuse + specular);
        }