Exemple #1
0
        public Vector ReflectAndRefract(Shape3D obj, Ray ray, Vector intersect, Vector normal, int depth)
        {
            // var cVec = obj.material.Intersect(ray, intersect, normal, obj).ToVector();
            var  cVec       = Vector.Build.Dense(3);
            var  lIntersect = intersect + (normal * 0.001f);
            bool outside    = Extensions.Dot3(ray.direction, normal) > 0.0f;

            if (obj.material.kReflection > 0f)
            {
                var reflect = Extensions.Reflected(-ray.direction, normal).Normalize();
                Ray r       = new Ray(lIntersect, reflect);
                SpawnRay(r, out var reflectColor, depth + 1);
                cVec += (reflectColor.ToVector() * obj.material.kReflection);
            }
            if (obj.material.kTransmission > 0f)
            {
                var refract = Extensions.Refract(ray.direction, normal, airKt,
                                                 obj.material.kTransmission).Normalize();
                var rO = outside ? intersect + (normal * 0.001f) : intersect - (normal * 0.001f);
                Ray r  = new Ray(rO, refract);
                SpawnRay(r, out var refractColor, depth + 1);
                cVec += (refractColor.ToVector() * obj.material.kTransmission);
            }
            return(cVec);
        }
Exemple #2
0
        public override bool Intersect(Ray ray, out Vector <float>[] intersection, out Vector <float>[] normal)
        {
            Shape3D closestT = null;

            intersection = new Vector[1];
            normal       = new Vector[1];
            float closestD = float.MaxValue;
            int   ti       = 0;

            foreach (Shape3D t in shapes)
            {
                if (t.Intersect(ray, out var i, out var n))
                {
                    float dist = Math.Abs((ray.origin - i[0]).Length());
                    if (dist < closestD)
                    {
                        closestD        = dist;
                        closestT        = t;
                        intersection[0] = i[0];
                        normal[0]       = n[0];
                    }
                }
                ti++;
            }
            return(closestT != null);
        }
Exemple #3
0
        public static bool IntersectObjects(List <Shape3D> L, Ray ray, ref Shape3D hitObject, ref Vector intersect, ref Vector normal)
        {
            // run intersection test
            Shape3D closestObj = null;
            float?  closestD   = null;

            if (hitObject != null)
            {
                closestObj = hitObject;
                closestD   = Math.Abs((ray.origin - intersect).Length());
            }
            foreach (Shape3D obj in L)
            {
                // if (obj.AABB.Intersect(ray, out var min, out var max))
                // {
                if (obj.Intersect(ray, out var i, out var n))
                {
                    float dist = Math.Abs((ray.origin - i[0]).Length());
                    if (closestD == null || dist < closestD)
                    {
                        closestD   = dist;
                        closestObj = obj;
                        intersect  = i[0];
                        normal     = n[0];
                    }
                }
                // }
            }
            if (closestObj != null)
            {
                hitObject = closestObj;
            }
            return(hitObject != null);
        }
Exemple #4
0
 public bool InBounds(Shape3D s)
 {
     if (s is Triangle)
     {
         return(InBounds(s as Triangle));
     }
     if (s.AABB != null)
     {
         return(InBounds(s.AABB));
     }
     else
     {
         System.Console.WriteLine("no AABB");
         return(false);
     }
     // else if (s is Sphere)
     // {
     //     return InBounds(s as Sphere);
     // }
     // else if (s is Plane)
     // {
     //     return InBounds(s as Plane);
     // }
     // else return false;
 }
Exemple #5
0
 public static bool Traverse(Ray ray, Node node, ref Shape3D hitObject, ref Vector intersect, ref Vector normal, int depth = 0)
 {
     // System.Console.WriteLine("Traversing Depth: " + depth);
     if (node is LeafNode)
     {
         var ln = node as LeafNode;
         // if(ln.bounds.Intersect(ray, out var min, out var max))
         IntersectObjects(ln.shapes, ray, ref hitObject, ref intersect, ref normal);
     }
     else
     {
         // traverse
         var ax = node.partition.axis;
         if (node.bounds.Intersect(ray, out var ad, out var bd))
         {
             var s = float.MaxValue;
             if (node.partition.Intersect(ray, out var splitIntersect, out var n))
             {
                 s = splitIntersect[0][ax];
             }
             float a, b;
             a = ray.origin[ax] + (ray.direction[ax] * ad);
             b = ray.origin[ax] + (ray.direction[ax] * bd);
             if (a <= s)
             {
                 if (b < s)
                 {
                     Traverse(ray, node.right, ref hitObject, ref intersect, ref normal, depth + 1);
                 }
                 else
                 {
                     if (b == s)
                     {
                         Traverse(ray, node.left, ref hitObject, ref intersect, ref normal, depth + 1);
                         Traverse(ray, node.right, ref hitObject, ref intersect, ref normal, depth + 1);
                     }
                     else
                     {
                         Traverse(ray, node.right, ref hitObject, ref intersect, ref normal, depth + 1);
                         Traverse(ray, node.left, ref hitObject, ref intersect, ref normal, depth + 1);
                     }
                 }
             }
             else
             {
                 if (b > s)
                 {
                     Traverse(ray, node.left, ref hitObject, ref intersect, ref normal, depth + 1);
                 }
                 else
                 {
                     Traverse(ray, node.left, ref hitObject, ref intersect, ref normal, depth + 1);
                     Traverse(ray, node.right, ref hitObject, ref intersect, ref normal, depth + 1);
                 }
             }
         }
     }
     return(hitObject != null);
 }
Exemple #6
0
        public Shape3D TraceRayKD(Ray ray, out Vector intersect, out Vector normal)
        {
            Shape3D hitObj = null;

            intersect = null;
            normal    = null;
            KDTree.Traverse(ray, tree, ref hitObj, ref intersect, ref normal);
            return(hitObj);
        }
Exemple #7
0
        public static ComplexObject LoadObjFile(string filename)
        {
            var            factory   = new ObjLoader.Loader.Loaders.ObjLoaderFactory();
            var            loader    = factory.Create();
            var            fs        = File.OpenRead(filename);
            var            result    = loader.Load(fs);
            List <Shape3D> objShapes = new List <Shape3D>();
            var            m         = new BasicMaterial(Rgba32.Gray);

            foreach (var g in result.Groups)
            {
                foreach (var f in g.Faces)
                {
                    Vector[] verts = new Vector[f.Count];
                    for (var fv = 0; fv < f.Count; fv++)
                    {
                        var    vx   = result.Vertices[f[fv].VertexIndex - 1].X;
                        var    vy   = result.Vertices[f[fv].VertexIndex - 1].Y;
                        var    vz   = result.Vertices[f[fv].VertexIndex - 1].Z;
                        Vector vert = Vector.Build.DenseOfArray(new float[] { vx, vy, vz });
                        verts[fv] = vert;
                    }
                    Shape3D shape = null;
                    // Vector c = Vector.Build.Dense(3);
                    // foreach (Vector v in verts)
                    // {
                    //     c += v;
                    // }
                    // c /= verts.Length;

                    // shape = new Sphere(c, 0.01f, m);

                    switch (f.Count)
                    {
                    case 3:
                        shape = new Triangle(verts, m);
                        break;

                    case 4:
                        shape = new Plane(verts, m);
                        break;

                    default:
                        shape = new Plane(verts, m);
                        break;
                    }
                    if (shape != null)
                    {
                        objShapes.Add(shape);
                    }
                }
            }
            ComplexObject obj = new ComplexObject(objShapes, m);

            return(obj);
        }
Exemple #8
0
        public Material GetMaterial(Shape3D obj, Vector <float> intersection)
        {
            var   tex = obj.GetTextureCoords(intersection);
            float row = tex[1] / checksize;
            float col = tex[0] / checksize;

            if ((int)row % 2 == (int)col % 2)
            {
                return(material1);
            }
            else
            {
                return(material2);
            }
        }
Exemple #9
0
        public Vector ReflectAndRefractKD(Shape3D obj, Ray ray, Vector intersect, Vector normal, int depth)
        {
            var cVec = Vector.Build.Dense(3);

            if (obj.material is LenseMaterial)
            {
                var   bh            = obj as BlackHole;
                var   sw_radius     = bh.Sradius;
                var   ray_to_center = obj.center - ray.origin;
                float tca           = ray_to_center.DotProduct(ray.direction);
                var   p             = ray.origin + (ray.direction * tca);
                var   d             = (float)Math.Abs((p - obj.center).Length());
                if (d < sw_radius)
                {
                    return(cVec);
                }
                var a              = (2 * sw_radius / d);
                var rO             = intersect - (normal * (0.001f));
                var rotationMatrix = obj.GetRotationMatrixAboutAxis(normal.CrossProduct(ray.direction).Normalize(), a);
                var refract        = (rotationMatrix * ray.direction.GetVector4()).SubVector(0, 3).Normalize();
                Ray r              = new Ray(rO, refract);
                SpawnRayKD(r, out var reflectColor, depth + 1);
                cVec += (reflectColor.ToVector());
            }
            if (obj.material.kReflection > 0f)
            {
                var lIntersect = intersect + (normal * 0.001f);
                var reflect    = Extensions.Reflected(-ray.direction, normal).Normalize();
                Ray r          = new Ray(lIntersect, reflect);
                SpawnRayKD(r, out var reflectColor, depth + 1);
                cVec += (reflectColor.ToVector() * obj.material.kReflection);
            }
            if (obj.material.kTransmission > 0f)
            {
                bool outside = Extensions.Dot3(ray.direction, normal) > 0.0f;
                var  n1      = airKt;
                var  n2      = obj.material.kTransmission;
                var  norm    = normal.Clone();
                var  refract = Extensions.Refract(ray.direction, norm, n1, n2).Normalize();
                var  rO      = outside ? intersect + (normal * 0.001f) : intersect - (normal * 0.001f);
                Ray  r       = new Ray(rO, refract);
                SpawnRayKD(r, out var refractColor, depth + 1);
                cVec += (refractColor.ToVector() * obj.material.kTransmission);
            }
            return(cVec);
        }
Exemple #10
0
        public Shape3D TraceRay(Ray ray, out Vector intersect, out Vector normal)
        {
            Shape3D closestObj = null;
            float?  closestD   = null;

            intersect = null;
            normal    = null;
            foreach (Shape3D obj in objects)
            {
                if (obj.Intersect(ray, out var i, out var n))
                {
                    float dist = Math.Abs((ray.origin - i[0]).Length());
                    if (closestD == null || dist < closestD)
                    {
                        closestD   = dist;
                        closestObj = obj;
                        intersect  = i[0];
                        normal     = n[0];
                    }
                }
            }
            return(closestObj);
        }
Exemple #11
0
        public bool SpawnRayKD(Ray ray, out Rgba32 color, int depth = 0)
        {
            if (depth > 4)
            {
                color = (ambientLight.ToVector() * ambientCoefficient).ToColor();//background;
                return(false);
            }
            var     cVec = Vector.Build.Dense(3);
            Shape3D obj  = TraceRayKD(ray, out var intersect, out var normal);

            if (obj != null)
            {
                cVec += obj.material.Intersect(ray, intersect, normal, obj, true).ToVector();
                cVec += ReflectAndRefractKD(obj, ray, intersect, normal, depth);
                color = cVec.ToColor();
                return(true);
            }
            else
            {
                color = (ambientLight.ToVector() * ambientCoefficient).ToColor();//background;
                return(false);
            }
        }
Exemple #12
0
        //////
        // Phong Illumination Model:
        //
        // L = ka * La                     <--- ambient
        //   + kd * [Li * Od  * (Si . N)] <--- diffuse
        //   + ks * [Li * Os  * (Ri . V) ^ ke)] <--- specular
        //
        // L - Final returned radiance (color value)
        // ka - ambient coefficient
        // La - world ambient radiance
        // kd - diffuse coefficient
        // ke - specular exponent
        // [] - summation of all the light sources (i)
        // Li - radiance of light i
        // Si - angle of incidence of light i
        // Ri - angle of reflectance of light i
        // V  - viewing angle
        //////
        public Rgba32 Illuminate(Ray ray, Vector isect, Vector normal, PhongMaterial material, Shape3D obj, bool KD = false)
        {
            // initialize Light (zeros)
            Vector L = Vector.Build.Dense(3);
            // add ambient lighting
            Vector La = world.ambientLight.ToVector();
            float  ka = world.ambientCoefficient;

            L += (La * ka);
            // add up diffuse/specular/reflection lighting for each light
            Vector Ld = Vector.Build.Dense(3);
            Vector Ls = Vector.Build.Dense(3);
            Vector Lr = Vector.Build.Dense(3);

            // object/material diffuse/specular colors
            Vector Od = material.diffuseColor.ToVector();
            Vector Os = material.specularColor.ToVector();

            // viewing direction
            Vector V = -ray.direction.Normalize();
            // shift intersection to avoid self-collision
            Vector lIntersection = isect + (normal * 0.001f);

            foreach (LightSource Li in world.GetLightSources())
            {
                // shadow ray
                Vector Sdir = (Li.center - lIntersection).Normalize();
                float  l_d  = Math.Abs((Li.center - lIntersection).Length());
                Ray    S    = new Ray(lIntersection, Sdir);
                // reflected ray
                Vector Rdir = Extensions.Reflected(Sdir, normal).Normalize();
                // Ray R = new Ray(lIntersection, Rdir);
                // check for shadow ray -> other object intersection
                bool  shaded = false;
                float shade  = 0.0f;
                if (KD)
                {
                    var s_shape = world.TraceRayKD(S, out var i, out var n);
                    if (s_shape != null)
                    {
                        var s_d = Math.Abs((isect - i[0]).Length());
                        if (s_d < l_d)
                        {
                            shaded = true;
                            shade  = 1.0f - Extensions.Clamp(s_shape.material.kTransmission, 0.0f, 1.0f);
                        }
                    }
                }
                else
                {
                    foreach (Shape3D o_obj in world.objects)
                    {
                        if (!o_obj.Equals(obj))
                        {
                            if (o_obj.Intersect(S, out var I, out var N))
                            {
                                shaded = true;
                                shade  = 1.0f - Extensions.Clamp(o_obj.material.kTransmission, 0.0f, 1.0f);
                            }
                        }
                    }
                }
                if (!shaded || shade < 1.0f)
                {
                    // diffuse
                    Vector LiOd        = Li.color.ToVector().Multiply(Od).Clamp(0.0f, 1.0f);
                    float  dist        = (float)Distance.Euclidean(Li.center, lIntersection);
                    float  attenuation = Li.strength / (dist * dist);
                    // System.Console.WriteLine(attenuation);
                    LiOd *= attenuation;
                    float SdotN = Sdir.DotProduct(normal).Clamp(0.0f, 1.0f);
                    Ld += (SdotN * LiOd);
                    Ld -= shade;
                    Ld.Clamp(0.0f, 1.0f);
                    // specular
                    Vector LiOs = Li.color.ToVector().Multiply(Os).Clamp(0.0f, 1.0f);
                    LiOs *= attenuation;
                    float RdotV = ((float)Math.Pow(Rdir.DotProduct(V), material.specularExponent)).Clamp(0.0f, 1.0f);
                    Ls += (RdotV * LiOs);
                    Ls -= shade;
                    Ls.Clamp(0.0f, 1.0f);
                }
            }
            Ld *= material.kDiffuse;
            Ls *= material.kSpecular;
            L  += (Ld + Ls);
            return(L.Clamp(0.0f, 1.0f).ToColor());
        }
Exemple #13
0
 public override Rgba32 Intersect(Ray ray, Vector intersection, Vector normal, Shape3D obj, bool KD = false)
 {
     return(this.color);
 }
Exemple #14
0
 public override Rgba32 Intersect(Ray ray, Vector <float> intersection, Vector <float> normal, Shape3D obj, bool KD = false)
 {
     return(GetMaterial(obj, intersection).Intersect(ray, intersection, normal, obj, KD));
 }
Exemple #15
0
 public abstract Rgba32 Intersect(Ray ray, Vector intersection, Vector normal, Shape3D obj, bool KD = false);
Exemple #16
0
 public override Rgba32 Intersect(Ray ray, Vector intersection, Vector normal, Shape3D obj, bool KD = false)
 {
     return(lightingModel.Illuminate(ray, intersection, normal.Normalize(), this, obj, KD));
 }
Exemple #17
0
 public void AddObject(Shape3D o)
 {
     o.objID = objects.Count;
     objects.Add(o);
 }