示例#1
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;
 }
示例#2
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;
        }
示例#3
0
 public override Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf)
 {
     Point org = ShapeSet.Sample (ls, ref Ns);
     Vector dir = MonteCarlo.UniformSampleSphere (u1, u2);
     if ((dir ^ Ns) < 0.0)
         dir *= -1.0;
     ray = new Ray (org, dir, 0.001, double.PositiveInfinity, time);
     pdf = ShapeSet.Pdf (org) * Util.InvTwoPi;
     Spectrum Ls = L (org, Ns, dir);
     return Ls;
 }
示例#4
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;
 }
示例#5
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;
        }
示例#6
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;
 }
示例#7
0
 public Point Sample(Point p, LightSample lightSample, ref Normal Ns)
 {
     double temp = 0.0;
     int sn = AreaDistribution.SampleDiscrete (lightSample.uComponent, ref temp);
     Point pt = Shapes[sn].Sample (p, lightSample.uPos[0], lightSample.uPos[1], ref Ns);
     // Find closest intersection of ray with shapes in _ShapeSet_
     Ray r = new Ray (p, pt - p, 0.001, double.PositiveInfinity);
     double rayEps = 0.0, thit = 1.0;
     bool anyHit = false;
     DifferentialGeometry dg = new DifferentialGeometry ();
     foreach (IShape shape in Shapes)
         anyHit |= shape.Intersect (r, ref thit, ref rayEps, ref dg);
     if (anyHit)
         Ns = new Normal (dg.n);
     return r.Apply (thit);
 }
示例#8
0
        public override Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf)
        {
            // Choose point on disk oriented toward infinite light direction
            Point worldCenter;
            double worldRadius;
            scene.WorldBound.BoundingSphere (out worldCenter, out worldRadius);
            Vector v1, v2;
            Util.CoordinateSystem (LightDir, out v1, out v2);
            double d1 = 0.0, d2 = 0.0;
            MonteCarlo.ConcentricSampleDisk (ls.uPos[0], ls.uPos[1], ref d1, ref d2);
            Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2);

            // Set ray origin and direction for infinite light ray
            ray = new Ray (Pdisk + worldRadius * LightDir, -LightDir, 0.0, double.PositiveInfinity, time);
            Ns = new Normal (ray.Direction);
            pdf = 1.0 / (Util.Pi * worldRadius * worldRadius);
            return L;
        }
示例#9
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]);
        }
示例#10
0
 public Point Sample(LightSample lightSample, ref Normal Ns)
 {
     double temp = 0.0;
     int sn = AreaDistribution.SampleDiscrete (lightSample.uComponent, ref temp);
     return Shapes[sn].Sample (lightSample.uPos[0], lightSample.uPos[1], ref Ns);
 }
示例#11
0
 public abstract Spectrum L(Point p, Normal n, Vector w);
示例#12
0
文件: BSDF.cs 项目: Kintaro/Hyperion
 public BSDF(DifferentialGeometry dgs, Normal ngeom)
     : this(dgs, ngeom, 1.0)
 {
 }
示例#13
0
 public virtual Point Sample(double u1, double u2, ref Normal Ns)
 {
     return new Point ();
 }
示例#14
0
        public override Point Sample(Point p, double u1, double u2, ref Normal Ns)
        {
            // Compute coordinate system for sphere sampling
            Point Pcenter = ObjectToWorld.Apply (new Point ());
            Vector wc = (Pcenter - p).Normalized;
            Vector wcX, wcY;
            Util.CoordinateSystem (wc, out wcX, out wcY);

            // Sample uniformly on sphere if $\pt{}$ is inside it
            if (Util.DistanceSquared (p, Pcenter) - Radius * Radius < 0.0001)
                return Sample (u1, u2, ref Ns);

            // Sample sphere uniformly inside subtended cone
            double sinThetaMax2 = Radius * Radius / Util.DistanceSquared (p, Pcenter);
            double cosThetaMax = Math.Sqrt (Math.Max (0.0, 1.0 - sinThetaMax2));
            DifferentialGeometry dgSphere = new DifferentialGeometry ();
            double thit = 0.0, rayEpsilon = 0.0;
            Point ps;
            Ray r = new Ray (p, MonteCarlo.UniformSampleCone (u1, u2, cosThetaMax, wcX, wcY, wc), 0.001);
            if (!Intersect (r, ref thit, ref rayEpsilon, ref dgSphere))
                thit = ((Pcenter - p) ^ r.Direction.Normalized);
            ps = r.Apply (thit);
            Ns = new Normal ((ps - Pcenter).Normalized);
            if (ReverseOrientation)
                Ns *= -1.0;
            return ps;
        }
示例#15
0
 public Normal(Normal vec)
     : this(vec.x, vec.y, vec.z)
 {
 }
示例#16
0
文件: Disk.cs 项目: Kintaro/Hyperion
        public override bool Intersect(Ray r, ref double tHit, ref double rayEpsilon, ref DifferentialGeometry dg)
        {
            // Transform _Ray_ to object space
            Ray ray = new Ray ();
            WorldToObject.Apply (r, ref ray);

            // Compute plane intersection for disk
            if (Math.Abs (ray.Direction.z) < 1E-07)
                return false;
            double thit = (Height - ray.Origin.z) / ray.Direction.z;
            if (thit < ray.MinT || thit > ray.MaxT)
                return false;

            // See if hit point is inside disk radii and $\phimax$
            Point phit = ray.Apply (thit);
            double dist2 = phit.x * phit.x + phit.y * phit.y;
            if (dist2 > Radius * Radius || dist2 < InnerRadius * InnerRadius)
                return false;

            // Test disk $\phi$ value against $\phimax$
            double phi = Math.Atan2 (phit.y, phit.x);
            if (phi < 0)
                phi += 2.0 * Util.Pi;
            if (phi > PhiMax)
                return false;

            // Find parametric representation of disk hit
            double u = phi / PhiMax;
            double v = 1.0 - ((Math.Sqrt (dist2) - InnerRadius) / (Radius - InnerRadius));
            Vector dpdu = new Vector (-PhiMax * phit.y, PhiMax * phit.x, 0.0);
            Vector dpdv = new Vector (-phit.x / (1 - v), -phit.y / (1 - v), 0.0);
            dpdu *= PhiMax * Util.InvTwoPi;
            dpdv *= (Radius - InnerRadius) / Radius;
            Normal dndu = new Normal (0, 0, 0), dndv = new Normal (0, 0, 0);

            // Initialize _DifferentialGeometry_ from parametric information
            dg = new DifferentialGeometry (ObjectToWorld.Apply (phit), ObjectToWorld.Apply (dpdu), ObjectToWorld.Apply (dpdv), ObjectToWorld.Apply (dndu), ObjectToWorld.Apply (dndv), u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 0.0005 * tHit;
            return true;
        }
示例#17
0
        public override void GetShadingGeometry(Transform objectToWorld, DifferentialGeometry dg, ref DifferentialGeometry dgShading)
        {
            if (Mesh.Normals == null && Mesh.Vectors == null)
            {
                dgShading = new DifferentialGeometry (dg);
                return;
            }
            // Initialize _Triangle_ shading geometry with _n_ and _s_
            // Compute barycentric coordinates for point
            double[] b = new double[3];

            // Initialize _A_ and _C_ matrices for barycentrics
            double[] uv = new double[6];
            GetUVs (uv);
            double[][] A = new double[][] { new double[] { uv[2] - uv[0], uv[4] - uv[0] }, new double[] { uv[3] - uv[1], uv[5] - uv[1] } };
            double[] C = new double[] { dg.u - uv[0], dg.v - uv[1] };
            if (!Util.SolveLinearSystem2x2 (A, C[0], C[1], out b[1], out b[2]))
            {
                // Handle degenerate parametric mapping
                b[0] = b[1] = b[2] = 1.0 / 3.0;
            } else
                b[0] = 1.0 - b[1] - b[2];

            // Use _n_ and _s_ to compute shading tangents for triangle, _ss_ and _ts_
            Normal ns;
            Vector ss, ts;
            if (Mesh.Normals != null)
                ns = objectToWorld.Apply (b[0] * Mesh.Normals[Vertices[0]] +
                    b[1] * Mesh.Normals[Vertices[1]] +
                    b[2] * Mesh.Normals[Vertices[2]]).Normalized;
            else
                ns = new Normal (dg.n);
            if (Mesh.Vectors != null)
                ss = objectToWorld.Apply (b[0] * Mesh.Vectors[Vertices[0]] +
                    b[1] * Mesh.Vectors[Vertices[1]] +
                    b[2] * Mesh.Vectors[Vertices[2]]).Normalized;
            else
                ss = dg.dpdu.Normalized;
            ts = ss % ns;
            if (ts.SquaredLength > 0.0)
            {
                ts = ts.Normalized;
                ss = ts % ns;
            } else
                Util.CoordinateSystem (new Vector (ns), out ss, out ts);
            Normal dndu, dndv;

            // Compute $\dndu$ and $\dndv$ for triangle shading geometry
            if (Mesh.Normals != null)
            {
                double[] uvs = new double[6];
                GetUVs (uvs);
                // Compute deltas for triangle partial derivatives of normal
                double du1 = uvs[0] - uvs[4];
                double du2 = uvs[2] - uvs[4];
                double dv1 = uvs[1] - uvs[5];
                double dv2 = uvs[3] - uvs[5];
                Normal dn1 = Mesh.Normals[Vertices[0]] - Mesh.Normals[Vertices[2]];
                Normal dn2 = Mesh.Normals[Vertices[1]] - Mesh.Normals[Vertices[2]];
                double determinant = du1 * dv2 - dv1 * du2;
                if (determinant == 0.0)
                {
                    dndu = new Normal (0, 0, 0);
                    dndv = new Normal (0, 0, 0);
                } else
                {
                    double invdet = 1.0 / determinant;
                    dndu = (dv2 * dn1 - dv1 * dn2) * invdet;
                    dndv = (-du2 * dn1 + du1 * dn2) * invdet;
                }
            } else
            {
                dndu = new Normal (0, 0, 0);
                dndv = new Normal (0, 0, 0);
            }
            dgShading = new DifferentialGeometry (dg.p, ss, ts, ObjectToWorld.Apply (dndu), ObjectToWorld.Apply (dndv), dg.u, dg.v, dg.Shape);
            dgShading.dudx = dg.dudx;
            dgShading.dvdx = dg.dvdx;
            dgShading.dudy = dg.dudy;
            dgShading.dvdy = dg.dvdy;
            dgShading.dpdx = new Vector (dg.dpdx);
            dgShading.dpdy = new Vector (dg.dpdy);
        }
示例#18
0
 public abstract Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf);
示例#19
0
文件: Util.cs 项目: Kintaro/Hyperion
 public static double AbsDot(Vector a, Normal b)
 {
     return Math.Abs (a ^ b);
 }
示例#20
0
文件: Util.cs 项目: Kintaro/Hyperion
 public static double AbsDot(Normal a, Vector b)
 {
     return Math.Abs (a ^ b);
 }
示例#21
0
文件: Util.cs 项目: Kintaro/Hyperion
 public static Normal FaceForward(Normal a, Normal b)
 {
     return ((a ^ b) < 0.0) ? -a : a;
 }
示例#22
0
        public override bool Intersect(Ray r, ref double tHit, ref double rayEpsilon, ref DifferentialGeometry dg)
        {
            double phi;
            Point phit;
            // Transform _Ray_ to object space
            Ray ray = new Ray ();
            WorldToObject.Apply (r, ref ray);

            // Compute quadratic sphere coefficients
            double A = ray.Direction.x * ray.Direction.x + ray.Direction.y * ray.Direction.y + ray.Direction.z * ray.Direction.z;
            double B = 2 * (ray.Direction.x * ray.Origin.x + ray.Direction.y * ray.Origin.y + ray.Direction.z * ray.Origin.z);
            double C = ray.Origin.x * ray.Origin.x + ray.Origin.y * ray.Origin.y + ray.Origin.z * ray.Origin.z - Radius * Radius;

            // Solve quadratic equation for _t_ values
            double t0 = 0.0, t1 = 0.0;
            if (!Util.Quadratic (A, B, C, ref t0, ref t1))
                return false;

            // Compute intersection distance along ray
            if (t0 > ray.MaxT || t1 < ray.MinT)
                return false;
            double thit = t0;
            if (t0 < ray.MinT)
            {
                thit = t1;
                if (thit > ray.MaxT)
                    return false;
            }

            // Compute sphere hit position and $\phi$
            phit = ray.Apply (thit);
            if (phit.x == 0.0 && phit.y == 0.0)
                phit.x = 1E-5 * Radius;
            phi = Math.Atan2 (phit.y, phit.x);
            if (phi < 0.0)
                phi += 2.0 * Util.Pi;

            // Test sphere intersection against clipping parameters
            if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
            {
                if (thit == t1)
                    return false;
                if (t1 > ray.MaxT)
                    return false;
                thit = t1;
                // Compute sphere hit position and $\phi$
                phit = ray.Apply (thit);
                if (phit.x == 0.0 && phit.y == 0.0)
                    phit.x = 1E-5f * Radius;
                phi = Math.Atan2 (phit.y, phit.x);
                if (phi < 0.0)
                    phi += 2.0 * Util.Pi;
                if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
                    return false;
            }

            // Find parametric representation of sphere hit
            double u = phi / PhiMax;
            double theta = Math.Acos (Util.Clamp (phit.z / Radius, -1.0, 1.0));
            double v = (theta - ThetaMin) / (ThetaMax - ThetaMin);

            // Compute sphere $\dpdu$ and $\dpdv$
            double zRadius = Math.Sqrt (phit.x * phit.x + phit.y * phit.y);
            double invzRadius = 1.0 / zRadius;
            double cosphi = phit.x * invzRadius;
            double sinphi = phit.y * invzRadius;
            Vector dpdu = new Vector (-PhiMax * phit.y, PhiMax * phit.x, 0);
            Vector dpdv = (ThetaMax - ThetaMin) * new Vector (phit.z * cosphi, phit.z * sinphi, -Radius * Math.Sin (theta));

            // Compute sphere $\dndu$ and $\dndv$
            Vector d2Pduu = -PhiMax * PhiMax * new Vector (phit.x, phit.y, 0);
            Vector d2Pduv = (ThetaMax - ThetaMin) * phit.z * PhiMax * new Vector (-sinphi, cosphi, 0.0);
            Vector d2Pdvv = -(ThetaMax - ThetaMin) * (ThetaMax - ThetaMin) * new Vector (phit.x, phit.y, phit.z);

            // Compute coefficients for fundamental forms
            double E = (dpdu ^ dpdu);
            double F = (dpdu ^ dpdv);
            double G = (dpdv ^ dpdv);
            Vector N = (dpdu % dpdv).Normalized;
            double e = (N ^ d2Pduu);
            double f = (N ^ d2Pduv);
            double g = (N ^ d2Pdvv);

            // Compute $\dndu$ and $\dndv$ from fundamental form coefficients
            double invEGF2 = 1.0 / (E * G - F * F);
            Normal dndu = new Normal ((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv);
            Normal dndv = new Normal ((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv);

            // Initialize _DifferentialGeometry_ from parametric information
            dg = new DifferentialGeometry (ObjectToWorld.Apply (phit), ObjectToWorld.Apply (dpdu), ObjectToWorld.Apply (dpdv), ObjectToWorld.Apply (dndu), ObjectToWorld.Apply (dndv), u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 0.0005 * tHit;

            return true;
        }
示例#23
0
 public override Spectrum L(Point p, Normal n, Vector w)
 {
     return (n ^ w) > 0.0 ? Lemit : new Spectrum ();
 }
示例#24
0
 public virtual Point Sample(Point p, double u1, double u2, ref Normal Ns)
 {
     return Sample (u1, u2, ref Ns);
 }
示例#25
0
        public override Point Sample(double u1, double u2, ref Normal Ns)
        {
            Point p1 = Mesh.Points[Vertices[0]];
            Point p2 = Mesh.Points[Vertices[1]];
            Point p3 = Mesh.Points[Vertices[2]];

            double b1, b2;
            MonteCarlo.UniformSampleTriangle (u1, u2, out b1, out b2);

            Point p = b1 * p1 + b2 * p2 + (1.0 - b1 - b2) * p3;
            Normal n = new Normal ((p2 - p1) % (p3 - p1));
            Ns = n.Normalized;
            if (ReverseOrientation)
                Ns *= -1.0;
            return p;
        }
示例#26
0
 public override Point Sample(double u1, double u2, ref Normal Ns)
 {
     Point p = new Point () + Radius * MonteCarlo.UniformSampleSphere (u1, u2);
     Ns = ObjectToWorld.Apply (new Normal (p.x, p.y, p.z)).Normalized;
     if (ReverseOrientation)
         Ns *= -1.0;
     return ObjectToWorld.Apply (p);
 }
示例#27
0
 public Vector(Normal vec)
     : this(vec.x, vec.y, vec.z)
 {
 }
示例#28
0
文件: Disk.cs 项目: Kintaro/Hyperion
 public override Point Sample(double u1, double u2, ref Normal Ns)
 {
     Point p = new Point ();
     MonteCarlo.ConcentricSampleDisk (u1, u2, ref p.x, ref p.y);
     p.x *= Radius;
     p.y *= Radius;
     p.z = Height;
     Ns = ObjectToWorld.Apply (new Normal (0, 0, 1)).Normalized;
     if (ReverseOrientation)
         Ns *= -1.0;
     return ObjectToWorld.Apply (p);
 }