예제 #1
0
파일: Util.cs 프로젝트: Kintaro/Hyperion
 public static double CosPhi(Vector w)
 {
     double sinTheta = SinTheta (w);
     if (sinTheta == 0.0)
         return 1.0;
     return Clamp (w.x / sinTheta, -1.0, 1.0);
 }
예제 #2
0
        public static Spectrum SpecularReflect(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample)
        {
            Vector wo = -ray.Direction, wi = new Vector ();
            double pdf = 0.0;
            Point p = bsdf.dgShading.p;
            Normal n = bsdf.dgShading.n;

            Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_REFLECTION | BxDFType.BSDF_SPECULAR);
            Spectrum L = new Spectrum ();

            if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0)
            {
                RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin = p + isect.dg.dpdx;
                    rd.RyOrigin = p + isect.dg.dpdy;

                    Normal dndx = bsdf.dgShading.dndu * bsdf.dgShading.dudx + bsdf.dgShading.dndv * bsdf.dgShading.dvdx;
                    Normal dndy = bsdf.dgShading.dndu * bsdf.dgShading.dudy + bsdf.dgShading.dndv * bsdf.dgShading.dvdy;
                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.Direction - wo;
                    double dDNdx = (dwodx ^ n) + (wo ^ dndx);
                    double dDNdy = (dwody ^ n) + (wo ^ dndy);
                    rd.RxDirection = wi - dwodx + 2 * new Vector ((wo ^ n) * dndx + dDNdx * n);
                    rd.RyDirection = wi - dwody + 2 * new Vector ((wo ^ n) * dndy + dDNdy * n);
                }

                Spectrum Li = renderer.Li (scene, rd, sample);
                L = f * Li * Util.AbsDot (wi, n) / pdf;
            }

            return L;
        }
예제 #3
0
 public static Vector CosineSampleHemisphere(double u1, double u2)
 {
     Vector ret = new Vector ();
     ConcentricSampleDisk (u1, u2, ref ret.x, ref ret.y);
     ret.z = Math.Sqrt (Math.Max (0.0, 1.0 - ret.x * ret.x - ret.y * ret.y));
     return ret;
 }
예제 #4
0
 public override Spectrum SampleF(Vector wo, ref Vector wi, double u1, double u2, ref double pdf)
 {
     Distribution.SampleF (wo, ref wi, u1, u2, ref pdf);
     if (!Util.SameHemisphere (wo, wi))
         return new Spectrum (0.0);
     return F (wo, wi);
 }
예제 #5
0
파일: Distant.cs 프로젝트: Kintaro/Hyperion
 public override Spectrum SampleL(Point p, double pEpsilon, LightSample ls, double time, ref Vector wi, ref double pdf, ref VisibilityTester visibility)
 {
     wi = new Vector (LightDir);
     pdf = 1.0;
     visibility.SetRay (p, pEpsilon, wi, time);
     return L;
 }
예제 #6
0
        public override Spectrum SampleF(Vector wo, ref Vector wi, double u1, double u2, ref double pdf)
        {
            bool entering = Util.CosTheta (wo) > 0.0;
            double ei = EtaI, et = EtaT;
            if (!entering)
            {
                double t = ei;
                ei = et;
                et = t;
            }

            // Compute transmitted ray direction
            double sini2 = Util.SinTheta2 (wo);
            double eta = ei / et;
            double sint2 = eta * eta * sini2;

            // Handle total internal reflection for transmission
            if (sint2 >= 1.0)
                return new Spectrum ();
            double cost = Math.Sqrt (Math.Max (0.0, 1.0 - sint2));
            if (entering)
                cost = -cost;
            double sintOverSini = eta;
            wi = new Vector (sintOverSini * -wo.x, sintOverSini * -wo.y, cost);
            pdf = 1.0;
            Spectrum F = Fresnel.Evaluate (Util.CosTheta (wo));
            return             /* (et*et)/(ei*ei) * */(new Spectrum (1.0) - F) * T / Util.AbsCosTheta (wi);
        }
예제 #7
0
        public override Spectrum F(Vector wo, Vector wi)
        {
            double sinThetaI = Util.SinTheta (wi);
            double sinThetaO = Util.SinTheta (wo);
            double maxCos = 0.0;

            if (sinThetaI > 1e-4 && sinThetaO > 1e-4)
            {
                double sinPhiI = Util.SinPhi (wi), cosPhiI = Util.CosPhi (wi);
                double sinPhiO = Util.SinPhi (wo), cosPhiO = Util.CosPhi (wo);
                double dcos = cosPhiI * cosPhiO + sinPhiI * sinPhiO;
                maxCos = Math.Max (0.0, dcos);
            }

            double sinAlpha, tanBeta;
            if (Util.AbsCosTheta (wi) > Util.AbsCosTheta (wo))
            {
                sinAlpha = sinThetaO;
                tanBeta = sinThetaI / Util.AbsCosTheta (wi);
            }
            else
            {
                sinAlpha = sinThetaI;
                tanBeta = sinThetaO / Util.AbsCosTheta (wo);
            }

            return R * Util.InvPi * (A + B * maxCos * sinAlpha * tanBeta);
        }
예제 #8
0
 public void ScaleDifferentials(double s)
 {
     RxOrigin = Origin + (RxOrigin - Origin) * s;
     RyOrigin = Origin + (RyOrigin - Origin) * s;
     RxDirection = Direction + (RxDirection - Direction) * s;
     RyDirection = Direction + (RyDirection - Direction) * s;
 }
예제 #9
0
 public double Pdf(Point p, Vector wi)
 {
     double pdf = 0.0;
     for (int i = 0; i < Shapes.Count; ++i)
         pdf += Areas[i] * Shapes[i].Pdf (p, wi);
     return pdf / SumArea;
 }
예제 #10
0
 public RayDifferential()
 {
     RxOrigin = new Point ();
     RyOrigin = new Point ();
     RxDirection = new Vector ();
     RyDirection = new Vector ();
     HasDifferentials = false;
 }
예제 #11
0
파일: BxDF.cs 프로젝트: Kintaro/Hyperion
        public virtual Spectrum SampleF(Vector wo, ref Vector wi, double u1, double u2, ref double pdf)
        {
            wi = MonteCarlo.CosineSampleHemisphere (u1, u2);
            if (wo.z < 0.0)
                wi.z *= -1.0;
            pdf = Pdf (wo, wi);

            return F (wo, wi);
        }
예제 #12
0
 public override Spectrum F(Vector wo, Vector wi)
 {
     double cosTheta0 = Math.Abs (Util.CosTheta (wo));
     double cosTheta1 = Math.Abs (Util.CosTheta (wi));
     Vector wh = (wi + wo).Normalized;
     double cosThetaH = (wi ^ wh);
     Spectrum F = Fresnel.Evaluate (cosThetaH);
     return R * Distribution.D (wh) * G (wo, wi, wh) * F / (4.0 * cosTheta1 * cosTheta0);
 }
예제 #13
0
파일: Blinn.cs 프로젝트: Kintaro/Hyperion
 public double Pdf(Vector wo, Vector wi)
 {
     Vector wh = (wo + wi).Normalized;
     double cosTheta = Util.AbsCosTheta (wh);
     double blinnPdf = ((Exponent + 1.0) * Math.Pow (cosTheta, Exponent)) / (2.0 * Util.Pi * 4.0 * (wo ^ wh));
     if ((wo ^ wh) <= 0.0)
         blinnPdf = 0.0;
     return blinnPdf;
 }
예제 #14
0
        private double G(Vector wo, Vector wi, Vector wh)
        {
            double NdotWh = Math.Abs (Util.CosTheta (wh));
            double NdotWo = Math.Abs (Util.CosTheta (wo));
            double NdotWi = Math.Abs (Util.CosTheta (wi));
            double W0dotWh = Util.AbsDot (wo, wh);

            return Math.Min (1.0, Math.Min ((2.0 * NdotWh * NdotWo / W0dotWh), (2.0 * NdotWh * NdotWi / W0dotWh)));
        }
예제 #15
0
파일: Ray.cs 프로젝트: Kintaro/Hyperion
 public Ray(Point origin, Vector direction, double start, double end, double time, int depth)
 {
     ++NumberOfRays;
     Origin = origin;
     Direction = direction;
     MinT = start;
     MaxT = end;
     Time = time;
     Depth = depth;
 }
예제 #16
0
파일: BSDF.cs 프로젝트: Kintaro/Hyperion
 public BSDF(DifferentialGeometry dgs, Normal ngeom, double eta)
 {
     dgShading = new DifferentialGeometry (dgs);
     Eta = eta;
     ng = new Normal (ngeom);
     nn = new Normal (dgShading.n);
     sn = dgShading.dpdu.Normalized;
     tn = nn % sn;
     nBxDFs = 0;
 }
예제 #17
0
파일: Ray.cs 프로젝트: Kintaro/Hyperion
 public Ray()
 {
     ++NumberOfRays;
     MinT = 0.0;
     MaxT = double.PositiveInfinity;
     Time = 0.0;
     Depth = 0;
     Origin = new Point ();
     Direction = new Vector ();
 }
예제 #18
0
        public override Spectrum SampleL(Point p, double pEpsilon, LightSample ls, double time, ref Vector wi, ref double pdf, ref VisibilityTester visibility)
        {
            Normal ns = new Normal ();
            Point ps = ShapeSet.Sample (p, ls, ref ns);
            wi = (ps - p).Normalized;
            pdf = ShapeSet.Pdf (p, wi);
            visibility.SetSegment (p, pEpsilon, ps, 0.001, time);
            Spectrum Ls = L (ps, ns, -wi);

            return Ls;
        }
예제 #19
0
파일: BxDF.cs 프로젝트: Kintaro/Hyperion
 public virtual Spectrum Rho(Vector wo, int nSamples, double[] samples)
 {
     Spectrum r = new Spectrum ();
     for (int i = 0; i < nSamples; ++i)
     {
         Vector wi = new Vector ();
         double pdf = 0.0;
         Spectrum f = SampleF (wo, ref wi, samples[2 * i], samples[2 * i + 1], ref pdf);
         if (pdf > 0.0)
             r += f * Util.AbsCosTheta (wi) / pdf;
     }
     return r / (double)nSamples;
 }
예제 #20
0
파일: Util.cs 프로젝트: Kintaro/Hyperion
 public static void CoordinateSystem(Vector v1, out Vector v2, out Vector v3)
 {
     if (Math.Abs (v1.x) > Math.Abs (v1.y))
     {
         double invLen = 1.0 / Math.Sqrt (v1.x * v1.x + v1.z * v1.z);
         v2 = new Vector (-v1.z * invLen, 0.0, v1.x * invLen);
     } else
     {
         double invLen = 1.0 / Math.Sqrt (v1.y * v1.y + v1.z * v1.z);
         v2 = new Vector (0.0, v1.z * invLen, -v1.y * invLen);
     }
     v3 = (v1 % v2);
 }
예제 #21
0
파일: BSDF.cs 프로젝트: Kintaro/Hyperion
 public Spectrum F(Vector woW, Vector wiW, BxDFType flags)
 {
     Vector wi = WorldToLocal (wiW), wo = WorldToLocal (woW);
     if ((wiW ^ ng) * (woW ^ ng) > 0)
         flags &= ~BxDFType.BSDF_TRANSMISSION;
     else
         flags &= ~BxDFType.BSDF_REFLECTION;
     Spectrum f = new Spectrum ();
     for (int i = 0; i < nBxDFs; ++i)
         if (bxdfs[i].MatchesFlags (flags))
             f += bxdfs[i].F (wo, wi);
     return f;
 }
예제 #22
0
        public Perspective(AnimatedTransform cameraToWorld, double[] screenWindow, double sopen, double sclose, double lensr, double focald, double fov, IFilm film)
            : base(cameraToWorld, Transform.Perspective (fov, 0.01, 1000.0), screenWindow, sopen, sclose, lensr, focald, film)
        {
            dxCamera = RasterToCamera.Apply (new Point (1.0, 0.0, 0.0)) - RasterToCamera.Apply (new Point (0.0, 0.0, 0.0));
            dyCamera = RasterToCamera.Apply (new Point (0.0, 1.0, 0.0)) - RasterToCamera.Apply (new Point (0.0, 0.0, 0.0));

            Console.WriteLine ("    - Creating Perspective Camera with settings:");
            Console.WriteLine ("       > ScreenWindow: [{0}, {1}, {2}, {3}]", screenWindow[0], screenWindow[1], screenWindow[2], screenWindow[3]);
            Console.WriteLine ("       > Shutter Open: {0}", sopen);
            Console.WriteLine ("       > Shutter Close: {0}", sclose);
            Console.WriteLine ("       > Lens Radius: {0}", lensr);
            Console.WriteLine ("       > Focal Distance: {0}", focald);
        }
예제 #23
0
 public DifferentialGeometry()
 {
     p = new Point ();
     n = new Normal ();
     dpdu = new Vector ();
     dpdv = new Vector ();
     dndu = new Normal ();
     dndv = new Normal ();
     dpdx = new Vector ();
     dpdy = new Vector ();
     u = v = 0.0;
     dudx = dudy = dvdx = dvdy = 0.0;
     Shape = null;
 }
예제 #24
0
파일: BxDF.cs 프로젝트: Kintaro/Hyperion
        public virtual Spectrum Rho(int nSamples, double[] samples1, double[] samples2)
        {
            Spectrum r = new Spectrum ();
            for (int i = 0; i < nSamples; ++i)
            {
                Vector wo, wi = new Vector ();
                wo = MonteCarlo.UniformSampleHemisphere (samples1[2 * i], samples1[2 * i + 1]);
                double pdf_o = Util.InvTwoPi, pdf_i = 0.0;
                Spectrum f = SampleF (wo, ref wi, samples2[2 * i], samples2[2 * i + 1], ref pdf_i);

                if (pdf_i > 0.0)
                    r += f * Util.AbsCosTheta (wi) * Util.AbsCosTheta (wo) / (pdf_o * pdf_i);
            }
            return r / (Util.Pi * nSamples);
        }
예제 #25
0
파일: Blinn.cs 프로젝트: Kintaro/Hyperion
        public void SampleF(Vector wo, ref Vector wi, double u1, double u2, ref double pdf)
        {
            double cosTheta = Math.Pow (u1, 1.0 / (Exponent + 1));
            double sinTheta = Math.Sqrt (Math.Max (0.0, 1.0 - cosTheta * cosTheta));
            double phi = u2 * 2.0 * Util.Pi;
            Vector wh = Util.SphericalDirection (sinTheta, cosTheta, phi);
            if (!Util.SameHemisphere (wo, wh))
                wh = -wh;

            wi = -wo + 2.0 * (wo ^ wh) * wh;
            double blinnPdf = ((Exponent + 1.0) * Math.Pow (cosTheta, Exponent)) / (2.0 * Util.Pi * 4.0 * (wo ^ wh));
            if ((wo ^ wh) <= 0.0)
                blinnPdf = 0.0;
            pdf = blinnPdf;
        }
예제 #26
0
        public DifferentialGeometry(Point p, Vector dpdu, Vector dpdv, Normal dndu, Normal dndv, double u, double v, IShape shape)
        {
            this.p = new Point (p);
            this.dpdu = new Vector (dpdu);
            this.dpdv = new Vector (dpdv);
            this.dndu = new Normal (dndu);
            this.dndv = new Normal (dndv);
            this.n = new Normal ((dpdu % dpdv).Normalized);
            this.u = u;
            this.v = v;
            dudx = dvdx = dudy = dvdy = 0.0;
            this.Shape = shape;

            if (shape != null && (shape.ReverseOrientation ^ shape.TransformSwapsHandedness))
                n *= -1.0;
        }
예제 #27
0
 public DifferentialGeometry(DifferentialGeometry dg)
 {
     this.p = new Point (dg.p);
     this.dpdu = new Vector (dg.dpdu);
     this.dpdv = new Vector (dg.dpdv);
     this.dndu = new Normal (dg.dndu);
     this.dndv = new Normal (dg.dndv);
     this.n = new Normal (dg.n);
     this.u = dg.u;
     this.v = dg.v;
     this.dudx = dg.dudx;
     this.dvdx = dg.dvdx;
     this.dudy = dg.dudy;
     this.dvdy = dg.dvdy;
     this.Shape = dg.Shape;
 }
예제 #28
0
        public TriangleMesh(Transform objectToWorld, Transform worldToObject, bool ro, int ntris, int nverts, int[] vptr, Point[] p, Normal[] n, Vector[] s, double[] uv,
        ITexture<double> atex)
            : base(objectToWorld, worldToObject, ro)
        {
            NumberOfTriangles = ntris;
            NumberOfVertices = nverts;
            AlphaTexture = atex;

            /*VertexIndices = new int[3 * NumberOfTriangles];
            vptr.CopyTo (VertexIndices, 0);*/
            VertexIndices = vptr;

            /*if (uv != null)
            {
                Uvs = new double[2 * NumberOfVertices];
                uv.CopyTo (Uvs, 0);
            }
            else
                Uvs = null;*/

            Points = new Point[NumberOfVertices];
            Normals = n;
            Vectors = s;
            Uvs = uv;

            /*if (n != null)
            {
                Normals = new Normal[NumberOfVertices];
                n.CopyTo (Normals, 0);
            }
            else
                Normals = null;

            if (s != null)
            {
                Vectors = new Vector[NumberOfVertices];
                s.CopyTo (Vectors, 0);
            }
            else
                Vectors = null;*/

            for (int i = 0; i < NumberOfVertices; ++i)
                Points[i] = objectToWorld.Apply (p[i]);
        }
예제 #29
0
        public static Spectrum SpecularTransmit(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample)
        {
            Vector wo = -ray.Direction, wi = new Vector ();
            double pdf = 0.0;
            Point p = bsdf.dgShading.p;
            Normal n = bsdf.dgShading.n;
            Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_TRANSMISSION | BxDFType.BSDF_SPECULAR);
            Spectrum L = new Spectrum ();

            if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0)
            {
                RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin = p + isect.dg.dpdx;
                    rd.RyOrigin = p + isect.dg.dpdy;

                    double eta = bsdf.Eta;
                    Vector w = -wo;

                    if ((wo ^ n) < 0.0)
                        eta = 1.0 / eta;

                    Normal dndx = bsdf.dgShading.dndu * bsdf.dgShading.dudx + bsdf.dgShading.dndv * bsdf.dgShading.dvdx;
                    Normal dndy = bsdf.dgShading.dndu * bsdf.dgShading.dudy + bsdf.dgShading.dndv * bsdf.dgShading.dvdy;

                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo;
                    double dDNdx = (dwodx ^ n) + (wo ^ dndx);
                    double dDNdy = (dwody ^ n) + (wo ^ dndy);
                    double mu = eta * (w ^ n) - (wi ^ n);
                    double dmudx = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdx;
                    double dmudy = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdy;

                    rd.RxDirection = wi + eta * dwodx - new Vector (mu * dndx + dmudx * n);
                    rd.RyDirection = wi + eta * dwody - new Vector (mu * dndy + dmudy * n);
                }

                Spectrum Li = renderer.Li (scene, rd, sample);
                L = f * Li * Util.AbsDot (wi, n) / pdf;
            }

            return L;
        }
예제 #30
0
        public static void Decompose(Matrix m, ref Vector T, ref Quaternion Rquat, ref Matrix S)
        {
            T.x = m.m[3];
            T.y = m.m[7];
            T.z = m.m[11];

            // Compute new transformation matrix _M_ without translation
            Matrix M = new Matrix (m);
            for (int i = 0; i < 3; ++i)
                M.m[i * 4 + 3] = M.m[12 + i] = 0.0;
            M.m[15] = 1.0;

            // Extract rotation _R_ from transformation matrix
            double norm;
            int count = 0;
            Matrix R = new Matrix (M);
            do
            {
                // Compute next matrix _Rnext_ in series
                Matrix Rnext = new Matrix ();
                Matrix Rit = R.Transposed.Inverse;
                for (int i = 0; i < 4; ++i)
                    for (int j = 0; j < 4; ++j)
                        Rnext.m[i * 4 + j] = 0.5 * (R.m[i * 4 + j] + Rit.m[i * 4 + j]);

                // Compute norm of difference between _R_ and _Rnext_
                norm = 0.0;
                for (int i = 0; i < 3; ++i)
                {
                    double n = Math.Abs (R.m[i * 4] - Rnext.m[i * 4]) + Math.Abs (R.m[i * 4 + 1] - Rnext.m[i * 4 + 1]) + Math.Abs (R.m[i * 4 + 2] - Rnext.m[i * 4 + 2]);
                    norm = Math.Max (norm, n);
                }
                R = Rnext;
            } while (++count < 100 && norm > 0.0001);
            // XXX TODO FIXME deal with flip...
            Rquat = new Quaternion (new Transform (R));

            // Compute scale _S_ using rotation and original matrix
            S = new Matrix (R.Inverse * M);
        }