Beispiel #1
0
        public Spectrum Li(Ray ray, Scene scene)
        {
            var L    = Spectrum.ZeroSpectrum;
            var beta = Spectrum.Create(1f);
            var specularReflection = false;

            for (int bounces = 0; bounces <= 20; ++bounces)
            {
                var(d, intersection) = scene.Intersect(ray);

                if (intersection == null)
                {
                    break;
                }

                var wo = -ray.d;
                if (intersection.Obj is Light)
                {
                    if (bounces == 0 || specularReflection)
                    {
                        L.AddTo(beta * intersection.Le(wo));
                    }
                    break;
                }

                L.AddTo(beta * Light.UniformSampleOneLight(intersection, scene));

                if (intersection.Obj is Shape objectHit)
                {
                    var(f, wi, pdf, isSpecular) = objectHit.BSDF.Sample_f(wo, intersection);
                    specularReflection          = isSpecular;

                    if (f.IsBlack() || Math.Abs(pdf) < double.Epsilon)
                    {
                        break;
                    }

                    beta *= f * Vector3.AbsDot(wi, intersection.Normal) / pdf;

                    ray = intersection.SpawnRay(wi);
                }

                if (bounces > 3)
                {
                    var q = 1 - beta.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }

                    beta /= 1.0 - q;
                }
            }

            return(L);
        }
Beispiel #2
0
        public Spectrum Li(Ray _r, Scene s)
        {
            var ray        = _r;
            var L          = Spectrum.ZeroSpectrum;
            var beta       = Spectrum.Create(1);
            int numBounces = 0;

            while (numBounces <= MAX_BOUCES)
            {
                // Test for intersections
                (double?t, SurfaceInteraction si) = s.Intersect(ray);

                if (si == null) // No hit
                {
                    break;
                }
                else if (si.Obj is Light) // Light hit
                {
                    if (numBounces == 0)
                    {
                        L = beta * si.Le(si.Wo);
                    }
                    break;
                }

                // Path reuse
                var Ld = Light.UniformSampleOneLight(si, s);
                L.AddTo(beta * Ld);

                // Diffuse
                Shape shape = si.Obj as Shape;
                (Spectrum f, Vector3 wi, double pdf, bool isSpecular) = shape.BSDF.Sample_f(si.Wo, si);

                // Redirect ray and accumulate beta
                ray   = new Ray(si.Point, wi);
                beta *= f * Vector3.AbsDot(wi, si.Normal) / pdf;

                // Russian roulette
                if (numBounces > 3)
                {
                    double q = 1.0 - beta.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    beta /= 1.0 - q;
                }

                ++numBounces;
            }

            return(L);
        }
Beispiel #3
0
        public override Spectrum f(Vector3 wo, Vector3 wi)
        {
            Vector3 wh = wo + wi;

            if (wh.z < 0.0)
            {
                wi = -wi;
                wh = -wh;
            }

            if (wh.LengthSquared() == 0.0) // epsilon ?
            {
                return(Spectrum.ZeroSpectrum);
            }

            wh = wh.Normalize();


            double  cos_phi_h   = Utils.CosPhi(wh);
            double  sin_phi_h   = Utils.SinPhi(wh);
            double  cos_theta_h = Utils.CosTheta(wh);
            double  sin_theta_h = Utils.SinTheta(wh);
            Vector3 w_hx        = new Vector3(cos_phi_h * cos_theta_h, sin_phi_h * cos_theta_h, -sin_theta_h);
            Vector3 w_hy        = new Vector3(-sin_phi_h, cos_phi_h, 0.0);
            Vector3 w_d         = new Vector3(Vector3.Dot(wi, w_hx), Vector3.Dot(wi, w_hy), Vector3.Dot(wi, wh));

            double theta_h = SphericalTheta(wh);
            double theta_d = SphericalTheta(w_d);
            double phi_d   = SphericalPhi(w_d);

            if (phi_d > Math.PI)
            {
                phi_d = phi_d - Math.PI;
            }


            // Get i.
            int theta_h_idx = ThetaHalfIndex(theta_h);
            int theta_d_idx = ThetaDiffIndex(theta_d);
            int phi_d_idx   = PhiDiffIndex(phi_d);
            int i           = phi_d_idx + (BRDF_SAMPLING_RES_PHI_D / 2) * (theta_d_idx + theta_h_idx * BRDF_SAMPLING_RES_THETA_D);

            return(Spectrum.Create(Vector <double> .Build.Dense(new[] { brdf[3 * i], brdf[3 * i + 1], brdf[3 * i + 2] })));
        }
Beispiel #4
0
        // FresnelDielectric Public Methods
        public Spectrum Evaluate(double cosThetaI)
        {
            var etaI = EtaI;
            var etaT = EtaT;

            if (etaI == 0 && etaT == 0)
            {
                // special case when we don't want Fresnel, e.g. always want perfect reflection (mirror)
                return(Spectrum.Create(1));
            }

            cosThetaI = cosThetaI.Clamp(-1, 1);
            // Potentially swap indices of refraction
            bool entering = cosThetaI > 0;

            if (!entering)
            {
                var t = etaI;
                etaI      = etaT;
                etaT      = t;
                cosThetaI = Math.Abs(cosThetaI);
            }

            // Compute _cosThetaT_ using Snell's law
            var sinThetaI = Math.Sqrt(Math.Max(0, 1 - cosThetaI * cosThetaI));
            var sinThetaT = etaI / etaT * sinThetaI;

            // Handle total public reflection
            if (sinThetaT >= 1)
            {
                return(Spectrum.Create(1));
            }
            var cosThetaT = Math.Sqrt(Math.Max(0, 1 - sinThetaT * sinThetaT));
            var Rparl     = ((etaT * cosThetaI) - (etaI * cosThetaT)) /
                            ((etaT * cosThetaI) + (etaI * cosThetaT));
            var Rperp = ((etaI * cosThetaI) - (etaT * cosThetaT)) /
                        ((etaI * cosThetaI) + (etaT * cosThetaT));

            return(Spectrum.Create((Rparl * Rparl + Rperp * Rperp) / 2));
        }
Beispiel #5
0
        public Spectrum f1(Vector3 wo, Vector3 wi)
        {
            Vector3 wh = wo + wi;

            if (wh.z < 0.0)
            {
                wi = -wi;
                wh = -wh;
            }

            if (wh.LengthSquared() == 0.0) // epsilon ?
            {
                return(Spectrum.ZeroSpectrum);
            }

            wh = wh.Normalize();


            double theta_half = Math.Acos(wh.z);
            double fi_half    = Math.Atan2(wh.y, wh.x);

            Vector3 normal   = new Vector3(0, 0, 1);
            Vector3 temp     = RotateVector(wi, normal, -fi_half);
            Vector3 biNormal = new Vector3(0, 1, 0);
            Vector3 diff     = RotateVector(temp, biNormal, -theta_half);

            double theta_diff = Math.Acos(diff.z);
            double fi_diff    = Math.Atan2(diff.y, diff.x);


            // Get i.
            int theta_h_idx = ThetaHalfIndex(theta_half);
            int theta_d_idx = ThetaDiffIndex(theta_diff);
            int phi_d_idx   = PhiDiffIndex(fi_diff);
            int i           = phi_d_idx + (BRDF_SAMPLING_RES_PHI_D / 2) * (theta_d_idx + theta_h_idx * BRDF_SAMPLING_RES_THETA_D);

            return(Spectrum.Create(Vector <double> .Build.Dense(new[] { brdf[3 * i], brdf[3 * i + 1], brdf[3 * i + 2] })));
        }
Beispiel #6
0
        public Spectrum Li(Ray r, Scene s)
        {
            /* BASIC Implement
            repeat
                r <- random ray from camera
                L <- 0, β <- 1, nbounces <- 0
                repeat
                   isect <- intersect r with scene
                   if isect == null // no hit
                      break
                   wo <- -r
                   if isect == light // light hit
                      L<- β*Le(wo) // add light emitted
                      break
                   wi <- random ray from isect
                   (f,pr) <- bsdf(isect,wi,wo)
                   β <- β*f*|cosθ|/pr
                   r <- wi
                   nbounces <- nbounces+1
                AddSampleToImage(L,r)
            */


            /* Russian Roulette Implement

            (f,pr) <- bsdf(isect,wi,wo)
            β <- β*f*|cosθ|/pr
            r <- wi
            if nbounces>3
            q <- 1 - max(β)
            if random() < q
            break
            β <- β/(1-q)

             */
            var L = Spectrum.ZeroSpectrum;
            var beta = Spectrum.Create((double)1);
            int nbounces = 0;
            double q;

            while(nbounces < 20) {
                (double? mint, SurfaceInteraction si) = s.Intersect(r);

                // If nothing hit end
                if (si == null) {
                    break;
                }

                // If Light hit include it and finish
                if (si.Obj is Light) {
                    if (nbounces == 0)
                    {
                        L = beta * si.Le(si.Wo);
                        //Console.WriteLine(beta.c);
                        //Console.WriteLine(L.c);
                    }
                    break;
                }

                // Sample light from SurfaceInteraction
                // TODO
                Spectrum Ld = Light.UniformSampleOneLight(si, s);

                L = L.AddTo(beta * Ld);
                
                // Make new reflected Ray
                //Ray wi = si.SpawnRay(UniformSampleSphere());
                
                // Get BSDF of hit object
                (Spectrum f, Vector3 wi, double pr, bool p) = (si.Obj as Shape).BSDF.Sample_f(si.Wo, si);

                // Update beta
                beta = beta * f * Utils.AbsCosTheta(wi) / pr;
                // Set reflected Ray as original Ray
                r = new Ray(si.Point, wi);

                if (nbounces > 3) {
                    q = 1 - beta.Max();
                    if (ThreadSafeRandom.NextDouble() < q) {
                        break;
                    }
                    beta /= (1 - q);
                }

                nbounces += 1;
            }
            Console.WriteLine(L.c);
            return L;
        }
Beispiel #7
0
        /// <summary>
        /// Generate Cornell Box Geometry
        /// </summary>
        /// <returns></returns>
        public static Scene CornellBox()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -800),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            //right
            el = new Quad(559.2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            s.Elements.Add(new DiffuseAreaLight(new Disk(80, 0.1, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));

            el = new Sphere(100, Transform.Translate(150, 100, 420));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Blue)));
            s.Elements.Add(el);

            el = new Sphere(100, Transform.Translate(400, 100, 230));
            // el.BSDF.Add(new MicrofacetReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1.5, 1, 0.05));
            // el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),0,0));
            // el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),1,1.5));
            el.BSDF.Add(new SpecularTransmission(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
            // el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            s.Elements.Add(el);

            return(s);
        }
Beispiel #8
0
        public static Scene OrenNayar2()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -800),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            //right
            el = new Quad(559.2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            s.Elements.Add(new DiffuseAreaLight(new Disk(80, 0.1, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));

            el = new Sphere(100, Transform.Translate(150, 100, 230));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            s.Elements.Add(el);

            el = new Sphere(100, Transform.Translate(400, 100, 230));
            el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow), 0.4));
            s.Elements.Add(el);

            return(s);
        }
Beispiel #9
0
        public static Scene SphereLightInner()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -800),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            //right
            el = new Quad(559.2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            el = new Sphere(100, Transform.Translate(150, 100, 420));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Blue)));
            s.Elements.Add(el);

            el = new Sphere(100, Transform.Translate(400, 100, 230));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            s.Elements.Add(el);

            var sphericalLight = new SphericalLight(1600.0, Transform.Translate(0, 0, 0), Spectrum.Create(1f), true);

            s.Elements.Add(sphericalLight);

            return(s);
        }
Beispiel #10
0
        public static Scene TestScene()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -800),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.5
            };

            Shape el;

            // Floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // Lights

            //s.Elements.Add(new DiffuseAreaLight(new Disk(2000, 0.1, Transform.Translate(278, 1000, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 1.5));
            s.Elements.Add(new DiffuseAreaLight(new Sphere(1000, Transform.Translate(278, 3000, 150)), Spectrum.Create(1), 12, DiffuseAreaLight.SideEnum.Front));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(2000, Transform.Translate(278, 548, 280)), Spectrum.Create(1), .8, DiffuseAreaLight.SideEnum.Back));



            el = new Sphere(100, Transform.Translate(150, 100, 230)); //.A(Transform.RotateY(-90)));
            el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow), 20.0));
            s.Elements.Add(el);

            el = new Sphere(100, Transform.Translate(400, 100, 230));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            s.Elements.Add(el);

            return(s);
        }
 public override Spectrum f(Vector3 wo, Vector3 wi)
 {
     (double r, double g, double b) = LookUpBRDFValue(wo, wi);
     //Console.WriteLine("{0} {1} {2}", (int)(r / RED_SCALE), (int)(g / GREEN_SCALE), (int)(b / BLUE_SCALE));
     return(Spectrum.Create(Vector <double> .Build.Dense(new[] { r, g, b })));
 }
Beispiel #12
0
        public Spectrum Li(Ray r, Scene s)
        {
            Spectrum L = Spectrum.ZeroSpectrum;
            Spectrum B = Spectrum.Create(1);

            int nbounces = 0;

            while (nbounces < 20)
            {
                SurfaceInteraction isect = null;

                //Get the object the ray intersected with
                isect = s.Intersect(r).Item2;

                //If the ray hasn't hit anything return 0
                if (isect == null)
                {
                    break;
                }

                Vector3 wo = isect.Wo;//-r.d;
                //If the ray hit a light, take its emission
                if (isect.Obj is Light)
                {
                    if (nbounces == 0)
                    {
                        L = B * isect.Le(wo);
                    }
                    break;
                }

                //Create a light ray from the intersection point and add its emission
                Spectrum Ld = Light.UniformSampleOneLight(isect, s);
                L = L.AddTo(B * Ld);


                //Get the materials value at this point
                (Spectrum f, Vector3 wi, double pr, bool specular) = (isect.Obj as Shape).BSDF.Sample_f(wo, isect);

                if (!specular)
                {
                    B = B * f * Utils.AbsCosTheta(wi) / pr;
                }


                //Spawn a new ray from the intersection
                r = isect.SpawnRay(wi);

                if (nbounces > 3)
                {
                    double q = 1.0 - B.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    B = B / (1 - q);
                }
                nbounces++;
            }

            return(L);
        }
        public Spectrum Li(Ray ray, Scene s)
        {
            var  L              = Spectrum.ZeroSpectrum;
            var  beta           = Spectrum.Create(1.0);
            bool specularBounce = false;

            for (int nBounces = 0; nBounces < 20; nBounces++)
            {
                (double?d, SurfaceInteraction si) = s.Intersect(ray);

                Vector3 wo = -ray.d;

                if (nBounces == 0 || specularBounce)
                {
                    if (d != null)
                    {
                        L.AddTo(beta * si.Le(wo));
                    }
                    else
                    {
                        foreach (var light in s.Lights)
                        {
                            L.AddTo(beta * Spectrum.ZeroSpectrum); // light.Le()
                        }
                    }
                }


                if (d == null)
                {
                    break;
                }


                if (si.Obj is Light)
                {
                    //if (nBounces == 0)
                    //{
                    //    L.AddTo(beta * si.Le(wo));
                    //}
                    break;
                }

                if (!specularBounce)
                {
                    L.AddTo(beta * Light.UniformSampleOneLight(si, s));
                }

                (Spectrum f, Vector3 wiW, double pdf, bool bxdfIsSpecular) = ((Shape)si.Obj).BSDF.Sample_f(wo, si);

                specularBounce = bxdfIsSpecular;

                if (f.IsBlack() || pdf == 0)
                {
                    break;
                }

                var wi = si.SpawnRay(wiW);

                beta = beta * f * Vector3.AbsDot(wiW, si.Normal) / pdf;
                ray  = wi;

                if (nBounces > 3)
                {
                    double q = 1 - beta.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    beta = beta / (1 - q);
                }
            }

            return(L);
        }
        /// <summary>
        /// Generate Cornell Box Geometry
        /// </summary>
        /// <returns></returns>
        public static Scene CornellBox()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.2
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            //right
            el = new Quad(559.2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            double shade     = 1;
            double intensity = 20;

            s.Elements.Add(new DiffuseAreaLight(new Quad(556, 200, Transform.Translate(278, 548, 559.2 - 400).A(Transform.RotateX(90))), Spectrum.Create(1), intensity));
            s.Elements.Add(new DiffuseAreaLight(new Quad(556, 200, Transform.Translate(278, 0.1, 559.2 - 400).A(Transform.RotateX(270))), Spectrum.Create(1), intensity));
            //s.Elements.Add(new RectangleLight(new Quad(556, 200, Transform.Translate(278, 548.8 / 2, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //s.Elements.Add(new RectangleLight(new Quad(100, 200, Transform.Translate(278, 548.8 * 3 / 4, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //s.Elements.Add(new RectangleLight(new Quad(100, 200, Transform.Translate(278, 548.8 * 1 / 4, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //left
            //s.Elements.Add(new DiffuseAreaLight(new Quad(548.8, 556.0, Transform.Translate(0.1, 548.8 / 2, 559.2).A(Transform.RotateY(90))), Spectrum.Create(shade), intensity));
            //right
            //s.Elements.Add(new DiffuseAreaLight(new Quad(548.8, 556.0, Transform.Translate(555.9, 548.8 / 2, 559.2).A(Transform.RotateY(270))), Spectrum.Create(shade), intensity));


            //s.Elements.Add(new DiffuseAreaLight(new Disk(80, 0.1, Transform.Translate(278, 0, 280).A(Transform.RotateX(-90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new RectangleLight(new Quad(160, 80, Transform.Translate(278, 278, 350).A(Transform.RotateX(135))), Spectrum.Create(1), 20));

            double gridSize   = 4;
            double sphereSize = 70;
            double offsetX    = 550 / gridSize;
            double offsetY    = 550 / gridSize;
            double row        = 0;
            double column     = 0;
            double z          = 400;

            string[] models =
            {
                "beige-fabric",         "yellow-matte-plastic", "green-plastic",      "neoprene-rubber",
                "blue-rubber",          "polyurethane-foam",    "special-walnut-224", "yellow-phenolic",
                "green-metallic-paint", "red-metallic-paint",   "violet-acrylic",     "grease-covered-steel",
                "aluminium",            "alum-bronze",          "two-layer-silver",   "two-layer-gold"
            };

            foreach (string model in models)
            {
                el = new Sphere(sphereSize, Transform.Translate((column + 0.5) * offsetX, (row + 0.5) * offsetY, z));

                column++;
                if (column % gridSize == 0)
                {
                    row++;
                    column = 0;
                }
                el.BSDF.Add(new MERL(model, true));
                //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
                s.Elements.Add(el);
            }



            return(s);
        }
Beispiel #15
0
        /// <summary>
        /// Generate Cornell Box Geometry
        /// </summary>
        /// <returns></returns>
        public static Scene CornellBox()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548), // -800
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 7                              // 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2 * 3, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2 * 3, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back2
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, -550).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);


            //double[] brdfs2 = ReadMerl.Read(@"D:\NRG seminarska\green-plastic.binary");
            //right
            el = new Quad(559.2 * 3, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            //el.BSDF.Add(new Merl(brdfs2));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2 * 3, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            // luč
            // kvadratna luč
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, 220).A(Transform.RotateX(90))), Spectrum.Create(1), 25));
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 25));

            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, 0).A(Transform.RotateX(90))), Spectrum.Create(1), 30));
            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(278, 548, 280)), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(60, Transform.Translate(278, 280, 300).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(400, 80, 400).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(1100, Transform.Translate(278, 280, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));

            double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\gold-metallic-paint.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-acrylic.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-diffuse-bball.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-fabric.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-fabric2.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-marble.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-paint.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\ss440.binary");

            // modra krogla
            //el = new Sphere(100, Transform.Translate(150, 100, 420));
            //el = new Sphere(130, Transform.Translate(180, 130, 400));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 0, 0));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Blue)));
            //el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Blue), 10));
            //el.BSDF.Add(new Merl(brdfs1));
            //s.Elements.Add(el);

            //rumena krogla
            //el = new Sphere(130, Transform.Translate(400, 130, 230));
            el = new Sphere(200, Transform.Translate(250, 200, 230));

            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),0,0));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),0.25,0.6));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            //el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow), 5));
            el.BSDF.Add(new Merl(brdfs0));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
            s.Elements.Add(el);


            //el = new Sphere(60, Transform.Translate(180, 60, 100));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            //s.Elements.Add(el);

            return(s);
        }
Beispiel #16
0
        public static Scene AllMerlInOne()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548), // -800
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5                              // 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2 * 2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2 * 2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back2
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, -550).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // right
            el = new Quad(559.2 * 2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            s.Elements.Add(el);

            // left
            el = new Quad(559.2 * 2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            // luč
            // kvadratna luč
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, 200).A(Transform.RotateX(90))), Spectrum.Create(1), 31));
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 35));



            DirectoryInfo d = new DirectoryInfo(@"D:\NRG seminarska\");

            FileInfo[] Files = d.GetFiles("*.binary");


            //int xOff = 25;
            //int yOff = 25;
            //int countSpheres = 0;
            //foreach (FileInfo file in Files)
            //{
            //    double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

            //    el = new Sphere(25, Transform.Translate(xOff, yOff, 400));
            //    el.BSDF.Add(new Merl(brdf0));
            //    s.Elements.Add(el);

            //    countSpheres++;
            //    xOff += 52;
            //    if (countSpheres % 10 == 0)
            //    {
            //        yOff += 52;
            //        xOff = 25;
            //    }

            //    if (countSpheres == 49)
            //    {
            //        //break;
            //    }
            //}


            //int xOff = 38;
            //int yOff = 38;
            //int countSpheres = 0;
            //foreach (FileInfo file in Files)
            //{
            //    //if (countSpheres < 49) {
            //    //    countSpheres++;
            //    //    continue;
            //    //}

            //    double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

            //    el = new Sphere(36, Transform.Translate(xOff, yOff, 480));
            //    el.BSDF.Add(new Merl(brdf0));
            //    s.Elements.Add(el);

            //    countSpheres++;
            //    xOff += 77;
            //    if (countSpheres % 7 == 0)
            //    {
            //        yOff += 77;
            //        xOff = 38;
            //    }

            //    if (countSpheres == 49) //49 //98
            //    {
            //        break;
            //    }
            //}


            int xOff         = 55;
            int yOff         = 55;
            int countSpheres = 0;

            foreach (FileInfo file in Files)
            {
                double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

                el = new Sphere(50, Transform.Translate(xOff, yOff, 480));
                el.BSDF.Add(new Merl(brdf0));
                el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
                s.Elements.Add(el);

                countSpheres++;
                xOff += 105;
                if (countSpheres % 5 == 0)
                {
                    yOff += 105;
                    xOff  = 55;
                }

                if (countSpheres == 25)
                {
                    break;
                }
            }



            return(s);
        }