예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
 public abstract bool Intersect(Ray ray, ref Hit hit, float tmin = 0f, float tmax = float.MaxValue);