//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); } }
/// <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); }