public Vector3 Trace(Ray ray, Sphere sphere) { Vector3 ambient = new Vector3(0f, 0f, 0f); Hit hit = new Hit(); if (sphere.Intersect(ray, ref hit, 0.001f)) { Vector3 lightDir = lightPosition - hit.point; lightDir.Normalize(); float attenuation = 1f / (lightDir.length * lightDir.length); Vector3 lightDir2 = lightPosition2 - hit.point; lightDir2.Normalize(); float attenuation2 = 1f / (lightDir2.length * lightDir2.length); return(attenuation * DiffuseLighting(hit.normal, lightDir) + attenuation2 * DiffuseLighting2(hit.normal, lightDir2)); } return(ambient); }
public override bool Intersect(Ray ray, ref Hit hit, float tmin = 0f, float tmax = float.MaxValue) { Vector3 oc = ray.origin - center; // Le rayon pointe-t-il vers la sphere ? float b = Vector3.Dot(oc, ray.direction); // Le rayon est-t-il suffisamment proche ? float c = Vector3.Dot(oc, oc) - radius * radius; float discriminant = b * b - c; if (discriminant > 0f) { float sqrD = (float)Math.Sqrt(discriminant); float t = (-b - sqrD); if (t < tmax && t > tmin) { hit.point = ray.Eval(t); hit.normal = (hit.point - center); hit.normal.Normalize(); return(true); } t = (-b + sqrD); if (t < tmax && t > tmin) { hit.point = ray.Eval(t); hit.normal = (hit.point - center); hit.normal.Normalize(); hit.t = t; return(true); } return(false); } else { return(false); } }
public Vector3 TracePhong(Ray ray, List <AbstractObject> abstractObjects, List <Light> lights) { Vector3 color = new Vector3(); bool isFirstLight = true; List <Hit> hits = new List <Hit>(); List <AbstractObject> objects = new List <AbstractObject>(); List <float> distances = new List <float>(); float minDistance = float.MaxValue; AbstractObject nearestObj = null; Hit hit = new RayTracer.Hit(); foreach (AbstractObject obj in abstractObjects) { if (obj.Intersect(ray, ref hit, 0.001f)) { float distance = (hit.point.x - ray.origin.x) * (hit.point.x - ray.origin.x) + (hit.point.y - ray.origin.y) * (hit.point.y - ray.origin.y) + (hit.point.z - ray.origin.z) * (hit.point.z - ray.origin.z); if (distance < minDistance) { minDistance = distance; nearestObj = obj; } } } if (nearestObj == null) { return(color); } foreach (Light l in lights) { hits.Clear(); objects.Clear(); distances.Clear(); Vector3 dir = (l.point - hit.point); dir.Normalize(); Ray newRay = new Ray(hit.point, dir); float distanceLight = (hit.point.x - l.point.x) * (hit.point.x - l.point.x) + (hit.point.y - l.point.y) * (hit.point.y - l.point.y) + (hit.point.z - l.point.z) * (hit.point.z - l.point.z); foreach (AbstractObject obj in abstractObjects) { if (obj == nearestObj) { continue; } Hit h = new Hit(); if (obj.Intersect(newRay, ref h, 0.001f)) { float distance = (h.point.x - hit.point.x) * (h.point.x - hit.point.x) + (h.point.y - hit.point.y) * (h.point.y - hit.point.y) + (h.point.z - hit.point.z) * (h.point.z - hit.point.z); if (distance > distanceLight) { continue; } int i = 0; for (; i < distances.Count && distances[i] < distance; i++) { ; } hits.Insert(i, h); objects.Insert(i, obj); distances.Insert(i, distance); } } float intensity = 0; float specular = 0; Material mat = nearestObj.material; if (l.mode == Light.LIGHT_MODE.AMBIANTE || l.mode == Light.LIGHT_MODE.PHONG) { //Vector3 ambiant = mat.color * mat.ambiante * l.color * l.intensite; intensity += mat.ambiante; //color += ambiant; } if (objects.Count > 0) { color = l.color * mat.color * l.intensite * intensity; return(color); } if (l.mode == Light.LIGHT_MODE.DIFFUSE || l.mode == Light.LIGHT_MODE.PHONG) { Vector3 lightDir = l.point - hit.point; lightDir.Normalize(); float attenuation = 1f / (lightDir.length * lightDir.length); float dot = Math.Max(0f, Vector3.Dot(hit.normal, lightDir)); intensity += attenuation * dot * mat.diffuse; //color += attenuation * l.color * dot * mat.color * mat.diffuse; } if (l.mode == Light.LIGHT_MODE.SPECULAIRE || l.mode == Light.LIGHT_MODE.PHONG) { Vector3 lightDir = l.point - hit.point; lightDir.Normalize(); Vector3 V = ray.origin - hit.point; V.Normalize(); float dot = Math.Max(0f, Vector3.Dot(hit.normal, lightDir)); if (dot > 0) { Vector3 R = hit.normal * 2 * Vector3.Dot(lightDir, hit.normal) - lightDir; float spec = (float)Math.Pow(Vector3.Dot(V, R), mat.speculaire * l.intensite); if (spec > 0) { specular = spec; } } //color += l.color * intensite; } if (intensity > 1) { intensity = 1; } color = l.color * mat.color * l.intensite * intensity; color += l.color * l.intensite * specular; } if (color.x > 1) { color.x = 1; } if (color.y > 1) { color.y = 1; } if (color.z > 1) { color.z = 1; } return(color); }
public abstract bool Intersect(Ray ray, ref Hit hit, float tmin = 0f, float tmax = float.MaxValue);