Пример #1
0
 public static float SinPhi(ref Vector w)
 {
     float sintheta = SinTheta(ref w);
     if (sintheta == 0.0f)
         return 0.0f;
     return MathUtility.Clamp(w.Y / sintheta, -1.0f, 1.0f);
 }
Пример #2
0
 public Spectrum Le(Vector wo)
 {
     var areaLight = _primitive.GetAreaLight();
     return (areaLight != null)
         ? areaLight.L(_dg.Point, _dg.Normal, wo)
         : Spectrum.CreateBlack();
 }
Пример #3
0
        public override Spectrum F(Vector wo, Vector wi)
        {
            float sinthetai = ReflectionUtilities.SinTheta(ref wi);
            float sinthetao = ReflectionUtilities.SinTheta(ref wo);
            // Compute cosine term of Oren-Nayar model
            float maxcos = 0.0f;
            if (sinthetai > 1e-4 && sinthetao > 1e-4)
            {
                float sinphii = ReflectionUtilities.SinPhi(ref wi);
                float cosphii = ReflectionUtilities.CosPhi(ref wi);
                float sinphio = ReflectionUtilities.SinPhi(ref wo);
                float cosphio = ReflectionUtilities.CosPhi(ref wo);
                float dcos = cosphii * cosphio + sinphii * sinphio;
                maxcos = Math.Max(0.0f, dcos);
            }

            // Compute sine and tangent terms of Oren-Nayar model
            float sinalpha, tanbeta;
            if (ReflectionUtilities.AbsCosTheta(ref wi) > ReflectionUtilities.AbsCosTheta(ref wo))
            {
                sinalpha = sinthetao;
                tanbeta = sinthetai / ReflectionUtilities.AbsCosTheta(ref wi);
            }
            else
            {
                sinalpha = sinthetai;
                tanbeta = sinthetao / ReflectionUtilities.AbsCosTheta(ref wo);
            }
            return _reflectance * MathUtility.InvPi * (_a + _b * maxcos * sinalpha * tanbeta);
        }
Пример #4
0
 public static Vector CosineSampleHemisphere(float u1, float u2)
 {
     var ret = new Vector();
     ConcentricSampleDisk(u1, u2, out ret.X, out ret.Y);
     ret.Z = MathUtility.Sqrt(Math.Max(0.0f, 1.0f - ret.X * ret.X - ret.Y * ret.Y));
     return ret;
 }
Пример #5
0
 public Vector TransformVector(ref Vector v)
 {
     float x = v.X, y = v.Y, z = v.Z;
     return new Vector(
         _m.M[0, 0] * x + _m.M[0, 1] * y + _m.M[0, 2] * z,
         _m.M[1, 0] * x + _m.M[1, 1] * y + _m.M[1, 2] * z,
         _m.M[2, 0] * x + _m.M[2, 1] * y + _m.M[2, 2] * z);
 }
Пример #6
0
 public virtual Spectrum SampleF(Vector wo, out Vector wi, float u1, float u2, out float pdf)
 {
     // Cosine-sample the hemisphere, flipping the direction if necessary
     wi = MonteCarloUtilities.CosineSampleHemisphere(u1, u2);
     if (wo.Z < 0.0f) wi.Z *= -1.0f;
     pdf = Pdf(wo, wi);
     return F(wo, wi);
 }
Пример #7
0
 public static Vector Cross(Normal v1, Vector v2)
 {
     float v1x = v1.X, v1y = v1.Y, v1z = v1.Z;
     float v2x = v2.X, v2y = v2.Y, v2z = v2.Z;
     return new Vector(
         (v1y * v2z) - (v1z * v2y),
         (v1z * v2x) - (v1x * v2z),
         (v1x * v2y) - (v1y * v2x));
 }
Пример #8
0
 public override Spectrum SampleL(Point p, float pEpsilon, LightSample ls,
     float time, out Vector wi, out float pdf,
     out VisibilityTester vis)
 {
     wi = _direction;
     pdf = 1.0f;
     vis = new VisibilityTester(p, pEpsilon, wi, time);
     return _radiance;
 }
Пример #9
0
 public override Spectrum SampleL(
     Point p, float pEpsilon, LightSample ls, float time, out Vector wi,
     out float pdf, out VisibilityTester vis)
 {
     wi = Vector.Normalize(_lightPosition - p);
     pdf = 1.0f;
     vis = new VisibilityTester(p, pEpsilon, _lightPosition, 0.0f, time);
     return _intensity / Point.DistanceSquared(_lightPosition, p);
 }
Пример #10
0
 public Bsdf(DifferentialGeometry dgShading, Normal nGeom, float eta = 1.0f)
 {
     _dgShading = dgShading;
     _ng = nGeom;
     _eta = eta;
     _nn = dgShading.Normal;
     _sn = Vector.Normalize(dgShading.DpDu);
     _tn = Normal.Cross(_nn, _sn);
     _bxdfs = new List<Bxdf>();
 }
Пример #11
0
        public override bool TryIntersect(Ray r, out float tHit,
            out float rayEpsilon, out DifferentialGeometry dg)
        {
            tHit = float.NegativeInfinity;
            rayEpsilon = 0.0f;
            dg = null;

            float phi;
            Point phit;
            float thit;
            if (!DoIntersection(r, out phi, out phit, out thit))
                return false;

            // Find parametric representation of cylinder hit
            float u = phi / _phiMax;
            float v = (phit.Z - _zMin) / (_zMax - _zMin);

            // Compute cylinder $\dpdu$ and $\dpdv$
            var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0);
            var dpdv = new Vector(0, 0, _zMax - _zMin);

            // Compute cylinder $\dndu$ and $\dndv$
            Vector d2Pduu = -_phiMax * _phiMax * new Vector(phit.X, phit.Y, 0);
            Vector d2Pduv = Vector.Zero, d2Pdvv = Vector.Zero;

            // Compute coefficients for fundamental forms
            float E = Vector.Dot(dpdu, dpdu);
            float F = Vector.Dot(dpdu, dpdv);
            float G = Vector.Dot(dpdv, dpdv);
            Vector N = Vector.Normalize(Vector.Cross(dpdu, dpdv));
            float e = Vector.Dot(N, d2Pduu);
            float f = Vector.Dot(N, d2Pduv);
            float g = Vector.Dot(N, d2Pdvv);

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

            // Initialize _DifferentialGeometry_ from parametric information
            var o2w = ObjectToWorld;
            dg = new DifferentialGeometry(o2w.TransformPoint(ref phit),
                o2w.TransformVector(ref dpdu), o2w.TransformVector(ref dpdv),
                o2w.TransformNormal(ref dndu), o2w.TransformNormal(ref dndv),
                u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 5e-4f * tHit;
            return true;
        }
Пример #12
0
 public PerspectiveCamera(
     AnimatedTransform cameraToWorld, float[] screenWindow, 
     float shutterOpen, float shutterClose, 
     float lensRadius, float focalDistance, 
     float fieldOfView,
     Film film)
     : base(cameraToWorld, Transform.Perspective(fieldOfView, 1e-2f, 1000.0f), screenWindow, shutterOpen, shutterClose, lensRadius, focalDistance, film)
 {
     // Compute differential changes in origin for perspective camera rays
     _dxCamera = RasterToCamera.TransformPoint(new Point(1, 0, 0)) - RasterToCamera.TransformPoint(new Point(0, 0, 0));
     _dyCamera = RasterToCamera.TransformPoint(new Point(0, 1, 0)) - RasterToCamera.TransformPoint(new Point(0, 0, 0));
 }
Пример #13
0
 public virtual Spectrum Rho(Vector wo, int numSamples, float[] samples)
 {
     Spectrum r = Spectrum.CreateBlack();
     for (int i = 0; i < numSamples; ++i)
     {
         // Estimate one term of $\rho_\roman{hd}$
         Vector wi;
         float pdf;
         Spectrum f = SampleF(wo, out wi, samples[2 * i], samples[2 * i + 1], out pdf);
         if (pdf > 0.0f) r += f * ReflectionUtilities.AbsCosTheta(ref wi) / pdf;
     }
     return r / numSamples;
 }
Пример #14
0
        public virtual float Pdf(Point p, Vector wi)
        {
            // Intersect sample ray with area light geometry
            var ray = new Ray(p, wi, 1e-3f);
            ray.Depth = -1; // temporary hack to ignore alpha mask
            float thit, rayEpsilon;
            DifferentialGeometry dgLight;
            if (!TryIntersect(ray, out thit, out rayEpsilon, out dgLight))
                return 0.0f;

            // Convert light sample weight to solid angle measure
            float pdf = Point.DistanceSquared(p, ray.Evaluate(thit)) / (Normal.AbsDot(dgLight.Normal, -wi) * Area);
            if (float.IsInfinity(pdf))
                pdf = 0.0f;
            return pdf;
        }
Пример #15
0
        public DifferentialGeometry(Point point, Vector dpdu, Vector dpdv,
            Normal dndu, Normal dndv, float u, float v, Shape shape)
        {
            Point = point;
            Normal = (Normal) Vector.Normalize(Vector.Cross(dpdu, dpdv));
            DpDu = dpdu;
            DpDv = dpdv;
            DnDu = dndu;
            DnDv = dndv;
            U = u;
            V = v;
            Shape = shape;

            if (shape != null && shape.ReverseOrientation != shape.TransformSwapsHandedness)
                Normal *= -1.0f;
        }
Пример #16
0
        private static void Decompose(Matrix4x4 m, out Vector t, out Quaternion r, out Matrix4x4 s)
        {
            // Extract translation _T_ from transformation matrix
            t.X = m.M[0, 3];
            t.Y = m.M[1, 3];
            t.Z = m.M[2, 3];

            // Compute new transformation matrix _M_ without translation
            Matrix4x4 M = m.Clone();
            for (int i = 0; i < 3; ++i)
                M.M[i, 3] = M.M[3, i] = 0.0f;
            M.M[3, 3] = 1.0f;

            // Extract rotation _R_ from transformation matrix
            float norm;
            int count = 0;
            Matrix4x4 R = M.Clone();
            do
            {
                // Compute next matrix _Rnext_ in series
                var Rnext = new Matrix4x4();
                var Rit = Matrix4x4.Invert(Matrix4x4.Transpose(R));
                for (int i = 0; i < 4; ++i)
                    for (int j = 0; j < 4; ++j)
                        Rnext.M[i, j] = 0.5f * (R.M[i, j] + Rit.M[i, j]);

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

            // Compute scale _S_ using rotation and original matrix
            s = Matrix4x4.Mul(Matrix4x4.Invert(R), M);
        }
Пример #17
0
        public override bool TryIntersect(Ray r, out float tHit,
            out float rayEpsilon, out DifferentialGeometry dg)
        {
            tHit = float.NegativeInfinity;
            rayEpsilon = 0.0f;
            dg = null;

            float phi, dist2, thit;
            Point phit;
            if (!DoIntersection(r, out phi, out dist2, out phit, out thit))
                return false;

            // Find parametric representation of disk hit
            float u = phi / _phiMax;
            float oneMinusV = ((MathUtility.Sqrt(dist2) - _innerRadius) / (_radius - _innerRadius));
            float invOneMinusV = (oneMinusV > 0.0f) ? (1.0f / oneMinusV) : 0.0f;
            float v = 1.0f - oneMinusV;
            var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0.0f);
            var dpdv = new Vector(-phit.X * invOneMinusV, -phit.Y * invOneMinusV, 0.0f);
            dpdu *= _phiMax * MathUtility.InvTwoPi;
            dpdv *= (_radius - _innerRadius) / _radius;
            Normal dndu = Normal.Zero, dndv = Normal.Zero;

            // Initialize _DifferentialGeometry_ from parametric information
            var o2w = ObjectToWorld;
            dg = new DifferentialGeometry(o2w.TransformPoint(ref phit),
                o2w.TransformVector(ref dpdu), o2w.TransformVector(ref dpdv),
                o2w.TransformNormal(ref dndu), o2w.TransformNormal(ref dndv),
                u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 5e-4f * tHit;
            return true;
        }
Пример #18
0
 public override Spectrum L(Point p, Normal n, Vector w)
 {
     throw new System.NotImplementedException();
 }
Пример #19
0
 public override float Pdf(Point p, Vector wi)
 {
     throw new System.NotImplementedException();
 }
Пример #20
0
 public override Spectrum SampleL(Point p, float pEpsilon, LightSample ls, float time, out Vector wi, out float pdf,
     out VisibilityTester vis)
 {
     throw new System.NotImplementedException();
 }
Пример #21
0
 public static Normal FaceForward(Normal n, Vector v)
 {
     return (Dot(n, v) < 0.0f) ? -n : n;
 }
Пример #22
0
 public static float Dot(Vector v1, Normal v2)
 {
     return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
 }
Пример #23
0
 public static float Dot(Normal n1, Vector n2)
 {
     return n1.X * n2.X + n1.Y * n2.Y + n1.Z * n2.Z;
 }
Пример #24
0
 public static Vector SphericalDirection(
     float sintheta, float costheta, float phi,
     Vector x, Vector y, Vector z)
 {
     return sintheta * MathUtility.Cos(phi) * x
         + sintheta * MathUtility.Sin(phi) * y 
         + costheta * z;
 }
Пример #25
0
        public void ComputeDifferentials(RayDifferential ray)
        {
            if (ray.HasDifferentials)
            {
                // Estimate screen space change in $\pt{}$ and $(u,v)$

                // Compute auxiliary intersection points with plane
                float d = -Normal.Dot(Normal, new Vector(Point.X, Point.Y, Point.Z));
                var rxv = new Vector(ray.RxOrigin.X, ray.RxOrigin.Y, ray.RxOrigin.Z);
                float tx = -(Normal.Dot(Normal, rxv) + d) / Normal.Dot(Normal, ray.RxDirection);
                if (float.IsNaN(tx))
                    throw new InvalidOperationException();
                Point px = ray.RxOrigin + tx * ray.RxDirection;
                var ryv = new Vector(ray.RyOrigin.X, ray.RyOrigin.Y, ray.RyOrigin.Z);
                float ty = -(Normal.Dot(Normal, ryv) + d) / Normal.Dot(Normal, ray.RyDirection);
                if (float.IsNaN(ty))
                    throw new InvalidOperationException();
                Point py = ray.RyOrigin + ty * ray.RyDirection;
                DpDx = px - Point;
                DpDy = py - Point;

                // Compute $(u,v)$ offsets at auxiliary points

                // Initialize _A_, _Bx_, and _By_ matrices for offset computation
                var A = new float[2, 2];
                var Bx = new float[2];
                var By = new float[2];
                var axes = new int[2];
                if (Math.Abs(Normal.X) > Math.Abs(Normal.Y) && Math.Abs(Normal.X) > Math.Abs(Normal.Z))
                {
                    axes[0] = 1;
                    axes[1] = 2;
                }
                else if (Math.Abs(Normal.Y) > Math.Abs(Normal.Z))
                {
                    axes[0] = 0;
                    axes[1] = 2;
                }
                else
                {
                    axes[0] = 0;
                    axes[1] = 1;
                }

                // Initialize matrices for chosen projection plane
                A[0, 0] = DpDu[axes[0]];
                A[0, 1] = DpDv[axes[0]];
                A[1, 0] = DpDu[axes[1]];
                A[1, 1] = DpDv[axes[1]];
                Bx[0] = px[axes[0]] - Point[axes[0]];
                Bx[1] = px[axes[1]] - Point[axes[1]];
                By[0] = py[axes[0]] - Point[axes[0]];
                By[1] = py[axes[1]] - Point[axes[1]];
                if (!Matrix4x4.SolveLinearSystem2x2(A, Bx, out DuDx, out DvDx))
                {
                    DuDx = 0.0f;
                    DvDx = 0.0f;
                }
                if (!Matrix4x4.SolveLinearSystem2x2(A, By, out DuDy, out DvDy))
                {
                    DuDy = 0.0f;
                    DvDy = 0.0f;
                }
            }
            else
            {
                DuDx = DvDx = 0.0f;
                DuDy = DvDy = 0.0f;
                DpDx = DpDy = Vector.Zero;
            }
        }
Пример #26
0
 public static float SphericalTheta(Vector v)
 {
     return MathUtility.Acos(MathUtility.Clamp(v.Z, -1.0f, 1.0f));
 }
Пример #27
0
 public static Vector UniformSampleCone(
     float u1, float u2, float costhetamax,
     ref Vector x, ref Vector y, ref Vector z)
 {
     float costheta = MathUtility.Lerp(u1, costhetamax, 1.0f);
     float sintheta = MathUtility.Sqrt(1.0f - costheta * costheta);
     float phi = u2 * 2.0f * MathUtility.Pi;
     return MathUtility.Cos(phi) * sintheta * x + MathUtility.Sin(phi) * sintheta * y + costheta * z;
 }
Пример #28
0
 public Vector TransformVector(float time, Vector v)
 {
     if (!_actuallyAnimated || time <= _startTime)
         return _startTransform.TransformVector(ref v);
     if (time >= _endTime)
         return _endTransform.TransformVector(ref v);
     Transform t;
     Interpolate(time, out t);
     return t.TransformVector(ref v);
 }
Пример #29
0
 public static float AbsDot(Normal v1, Vector v2)
 {
     return Math.Abs(Dot(v1, v2));
 }
Пример #30
0
 public static float SphericalPhi(Vector v)
 {
     float p = MathUtility.Atan2(v.Y, v.X);
     return (p < 0.0f) ? p + 2.0f * MathUtility.Pi : p;
 }