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); }
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; }
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; }
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); }
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; }
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); }
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); }
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; }
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; }
public RayDifferential() { RxOrigin = new Point (); RyOrigin = new Point (); RxDirection = new Vector (); RyDirection = new Vector (); HasDifferentials = false; }
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); }
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); }
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; }
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))); }
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; }
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; }
public Ray() { ++NumberOfRays; MinT = 0.0; MaxT = double.PositiveInfinity; Time = 0.0; Depth = 0; Origin = new Point (); Direction = new Vector (); }
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; }
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; }
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); }
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; }
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); }
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; }
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); }
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; }
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; }
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; }
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]); }
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; }
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); }