예제 #1
0
        public static World GetComplexWorld(int width, int height)
        {
            // World world = GetDefaultWorld(width, height);
            World       world     = new World(width, height);
            Vector      lightPos2 = Vector.Build.DenseOfArray(new float[] { 1.0f, -3.0f, -3.0f });
            LightSource l2        = new LightSource(lightPos2, Rgba32.White, 95.5f);

            world.AddLightSource(l2);

            // initialize camera
            Vector cameraPos    = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -10.0f });
            Vector cameraUp     = Vector.Build.DenseOfArray(new float[] { 0.0f, 1.0f, 0.0f });
            Vector cameraLookAt = Vector.Build.DenseOfArray(new float[] { -0.2f, 0.0f, -4.0f });

            world.cameras.Add(new Camera(cameraPos, cameraLookAt, cameraUp, world));

            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);

            var complex = OBJParser.LoadObjFile("./data/gourd.obj");

            // complex.Translate(0.0f, -0.5f, 0.0f);
            System.Console.WriteLine(complex.shapes.Count);
            // complex.RotateZ((float)Math.PI);
            // complex.Translate(0.0f, 0.2f, -2.0f);
            // complex.Scale(1.2f, 1.2f, 1.2f);
            var mat = PhongMaterial.Red(illuminationModel);

            mat.kSpecular = 0.01f;
            complex.SetMaterial(mat);
            world.AddObject(complex);
            return(world);
        }
예제 #2
0
        public static World GetManyBallWorld(int width, int height)
        {
            var world = GetDefaultWorld(width, height);
            // world.objects = new List<Shape3D>();
            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);
            var r      = new Random();
            var center = Vector.Build.DenseOfArray(new float[] { 0.0f, -0.3f, 3.5f });
            var radius = 0.3f;
            var mir    = Mirror.GetMirror(illuminationModel);
            var glass  = TransmissiveMaterial.GetTransmissiveMaterial(illuminationModel);
            var blue   = PhongMaterial.Blue(illuminationModel);

            for (int i = 0; i < 100; i++)
            {
                var rVec = Vector.Build.DenseOfArray(new float[] {
                    (float)(r.NextDouble() * 2) - 1,
                    (float)(r.NextDouble() * 2) - 1,
                    (float)(r.NextDouble() * 2) - 1
                });
                rVec = rVec.Normalize();
                var rC = center + (rVec * radius);
                // PhongMaterial mat = mir;
                PhongMaterial mat  = (i % 2 == 0) ? mir : blue;//(PhongMaterial)glass;
                Sphere        ball = new Sphere(rC, (float)(r.NextDouble() * 0.01f), mat);
                world.AddObject(ball);
            }
            return(world);
        }
예제 #3
0
        public static World GetVoxelTestWorld(int width, int height)
        {
            // World world = GetDefaultWorld(width, height);
            World world = new World(width, height);
            // initialize light source
            Vector      lightPos = Vector.Build.DenseOfArray(new float[] { -3.0f, -3.0f, -3.0f });
            LightSource l1       = new LightSource(lightPos, Rgba32.White, 95.5f);

            world.AddLightSource(l1);

            // initialize camera
            Vector cameraPos    = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -3.0f });
            Vector cameraUp     = Vector.Build.DenseOfArray(new float[] { 0.0f, -1.0f, 0.0f });
            Vector cameraLookAt = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, 0.0f });

            world.cameras.Add(new Camera(cameraPos, cameraLookAt, cameraUp, world));

            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);

            var c = Vector.Build.Dense(3);

            c[0] = 0.0f;
            c[1] = 0.0f;
            c[2] = 0.0f;
            var s    = Vector.Build.DenseOfArray(new float[] { 1.0f, 1.0f, 1.0f });
            var rmat = PhongMaterial.Red(illuminationModel);
            var bmat = PhongMaterial.Blue(illuminationModel);
            var gmat = PhongMaterial.Green(illuminationModel);

            var p = new PartitionPlane(c, 1);

            Voxel main = new Voxel(c, s);

            Voxel[] split = main.Split(p);
            Voxel   left  = new Voxel(split[0].center, split[0].size, rmat);
            Voxel   right = new Voxel(split[1].center, split[1].size, bmat);

            for (int i = 0; i < 6; i++)
            {
                world.AddObject(left.planes[i]);
                world.AddObject(right.planes[i]);
            }

            var smax = new Sphere(main.max, 0.05f, gmat);
            var smin = new Sphere(main.min, 0.05f, gmat);

            world.AddObject(smax);
            world.AddObject(smin);
            return(world);
        }
예제 #4
0
        public static World GetBlackHoleWorld(int width, int height)
        {
            World world = new World(width, height, Rgba32.Black);
            // initialize light source
            Vector      lightPos = Vector.Build.DenseOfArray(new float[] { -15.0f, 0f, 130.0f });
            LightSource l1       = new LightSource(lightPos, Rgba32.White, 150.0f);

            world.AddLightSource(l1);

            Vector      lightPos2 = Vector.Build.DenseOfArray(new float[] { 15.0f, 0f, 130.0f });
            LightSource l2        = new LightSource(lightPos2, Rgba32.White, 150.0f);

            world.AddLightSource(l2);

            // initialize camera
            Vector cameraPos    = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, 0.0f });
            Vector cameraUp     = Vector.Build.DenseOfArray(new float[] { 0.0f, -1.0f, 0.0f });
            Vector cameraLookAt = Vector.Build.DenseOfArray(new float[] { 0f, 0.0f, 15.0f });

            world.cameras.Add(new Camera(cameraPos, cameraLookAt, cameraUp, world));

            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);

            var   max_z1_c = Vector.Build.DenseOfArray(new float[] { -50.0f, 0.0f, 150.0f });
            var   max_z1_n = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -1.0f });
            var   mat1     = PhongMaterial.Red(illuminationModel);
            Plane max_z1   = new Plane(max_z1_c, max_z1_n, 100.0f, 100.0f, mat1);

            var   max_z2_c = Vector.Build.DenseOfArray(new float[] { 50.0f, 0.0f, 150.0f });
            var   max_z2_n = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -1.0f });
            var   mat2     = PhongMaterial.Blue(illuminationModel);
            Plane max_z2   = new Plane(max_z2_c, max_z2_n, 100.0f, 100.0f, mat2);

            var       bh_c  = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, 50.0f });
            var       bh_sr = 1.5f;
            BlackHole bh    = new BlackHole(bh_c, 3.0f, bh_sr);

            bh.material = new LenseMaterial(illuminationModel);
            world.AddObject(bh);
            world.AddObject(max_z1);
            world.AddObject(max_z2);
            return(world);
        }
예제 #5
0
        public static World GetBoxWorld(int width, int height)
        {
            var world = GetDefaultWorld(width, height);

            world.objects = new List <Shape3D>();
            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);

            Rgba32[]             p01colors         = new Rgba32[] { Rgba32.Red, Rgba32.White };
            float[]              p01coefficients   = new float[] { 0.9f, 0.3f };
            Rgba32[]             p02colors         = new Rgba32[] { Rgba32.Yellow, Rgba32.White };
            float[]              p02coefficients   = new float[] { 0.9f, 0.3f };
            PhongMaterial        pm0               = new PhongMaterial(illuminationModel, p01colors, p01coefficients, 10.0f);
            PhongMaterial        pm1               = new PhongMaterial(illuminationModel, p02colors, p02coefficients, 10.0f);
            CheckerboardMaterial p0checkerMaterial = new CheckerboardMaterial(pm0, pm1, 0.05f);

            var   max_y_c = Vector.Build.DenseOfArray(new float[] { 0.0f, -2.0f, 0.0f });
            var   max_y_n = Vector.Build.DenseOfArray(new float[] { 0.0f, -1.0f, 0.0f });
            Plane max_y   = new Plane(max_y_c, max_y_n, 5.0f, 10.0f, p0checkerMaterial);

            var   max_x_c = Vector.Build.DenseOfArray(new float[] { 1.0f, 0.0f, 0.0f });
            var   max_x_n = Vector.Build.DenseOfArray(new float[] { -1.0f, 0.0f, 0.0f });
            Plane max_x   = new Plane(max_x_c, max_x_n, 5.0f, 10.0f, p0checkerMaterial);

            var   min_x_c = Vector.Build.DenseOfArray(new float[] { -1.0f, 0.0f, 0.0f });
            var   min_x_n = Vector.Build.DenseOfArray(new float[] { 1.0f, 0.0f, 0.0f });
            Plane min_x   = new Plane(min_x_c, min_x_n, 5.0f, 10.0f, p0checkerMaterial);

            var   min_z_c = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -10.0f });
            var   min_z_n = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.01f, -1.0f });
            Plane min_z   = new Plane(min_z_c, min_z_n, 5.0f, 10.0f, p0checkerMaterial);

            var   max_z_c = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, 3.0f });
            var   max_z_n = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.01f, 1.0f });
            Plane max_z   = new Plane(min_z_c, max_z_n, 5.0f, 10.0f, p0checkerMaterial);

            return(world);
        }
예제 #6
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());
        }
예제 #7
0
        public static World GetDefaultWorld(int width, int height)
        {
            World world = new World(width, height, Rgba32.Black);
            // initialize light source
            Vector      lightPos = Vector.Build.DenseOfArray(new float[] { 0.0f, -0.4f, -5.0f });
            LightSource l1       = new LightSource(lightPos, Rgba32.White, 10.0f);

            world.AddLightSource(l1);

            // initialize camera
            Vector cameraPos    = Vector.Build.DenseOfArray(new float[] { -0.0f, -0.3f, -5.0f });
            Vector cameraUp     = Vector.Build.DenseOfArray(new float[] { 0.0f, -1.0f, 0.0f });
            Vector cameraLookAt = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, 0.0f });

            world.cameras.Add(new Camera(cameraPos, cameraLookAt, cameraUp, world));

            PhongIlluminationModel illuminationModel = new PhongIlluminationModel(world);

            // sphere 0
            Vector s0Center = Vector.Build.DenseOfArray(new float[] { -0.0f, -0.05f, -2.75f });
            float  s0Radius = 0.15f;

            Rgba32[]      s0colors        = new Rgba32[] { Rgba32.Blue, Rgba32.White };
            float[]       s0coefficients  = new float[] { 0.0f, 0.0f };
            PhongMaterial s0PhongMaterial = new PhongMaterial(illuminationModel, s0colors, s0coefficients, 7.0f);

            s0PhongMaterial.kTransmission = 0.95f;
            Sphere sphere0 = new Sphere(s0Center, s0Radius, s0PhongMaterial);

            // sphere 1
            Vector s1Center = Vector.Build.DenseOfArray(new float[] { -0.0f, -0.1f, -1.75f });
            float  s1Radius = 0.15f;

            Rgba32[]             s1colors          = new Rgba32[] { Rgba32.Silver, Rgba32.White };
            float[]              s1coefficients    = new float[] { 0.1f, 0.1f };
            PhongMaterial        s1PhongMaterial   = new PhongMaterial(illuminationModel, s1colors, s1coefficients, 10.0f);
            CheckerboardMaterial s1checkerMaterial = new CheckerboardMaterial(s1PhongMaterial, s0PhongMaterial, 0.1f);

            s1PhongMaterial.kReflection = 0.9f;
            Sphere sphere1 = new Sphere(s1Center, s1Radius, Mirror.GetMirror(illuminationModel));

            // plane0 (floor)
            Vector p0Center = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.2f, 0.0f });
            Vector p0Normal = Vector.Build.DenseOfArray(new float[] { 0.0f, -1.0f, 0.0f });

            Rgba32[]             p01colors         = new Rgba32[] { Rgba32.Red, Rgba32.White };
            float[]              p01coefficients   = new float[] { 0.9f, 0.1f };
            Rgba32[]             p02colors         = new Rgba32[] { Rgba32.Yellow, Rgba32.White };
            float[]              p02coefficients   = new float[] { 0.9f, 0.1f };
            PhongMaterial        pm0               = new PhongMaterial(illuminationModel, p01colors, p01coefficients, 10.0f);
            PhongMaterial        pm1               = new PhongMaterial(illuminationModel, p02colors, p02coefficients, 10.0f);
            CheckerboardMaterial p0checkerMaterial = new CheckerboardMaterial(pm0, pm1, 0.12f);

            p0checkerMaterial.kReflection = 0.0f;
            Plane plane0 = new Plane(p0Center, p0Normal, 3.0f, 8.0f, p0checkerMaterial);


            var   max_y_c = Vector.Build.DenseOfArray(new float[] { 0.0f, -0.8f, 5.0f });
            var   max_y_n = Vector.Build.DenseOfArray(new float[] { 0.0f, 0.0f, -1.0f });
            Plane max_y   = new Plane(max_y_c, max_y_n, 3.0f, 3.0f, Mirror.GetMirror(illuminationModel));

            world.AddObject(sphere0);
            world.AddObject(sphere1);
            world.AddObject(plane0);
            // world.AddObject(max_y);

            return(world);
        }