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>(); }
public Intersection(DifferentialGeometry dg, Primitive primitive, Transform objectToWorld, Transform worldToObject, float rayEpsilon) { _dg = dg; _primitive = primitive; WorldToObject = worldToObject; ObjectToWorld = objectToWorld; _rayEpsilon = rayEpsilon; }
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; }
protected static DifferentialGeometry Bump(Texture<float> d, DifferentialGeometry dgGeom, DifferentialGeometry dgs) { // Compute offset positions and evaluate displacement texture DifferentialGeometry dgEval = dgs; // Shift _dgEval_ _du_ in the $u$ direction float du = .5f * (Math.Abs(dgs.DuDx) + Math.Abs(dgs.DuDy)); if (du == 0.0f) du = .01f; dgEval.Point = dgs.Point + du * dgs.DpDu; dgEval.U = dgs.U + du; dgEval.Normal = Normal.Normalize((Normal) Vector.Cross(dgs.DpDu, dgs.DpDv) + du * dgs.DnDu); float uDisplace = d.Evaluate(dgEval); // Shift _dgEval_ _dv_ in the $v$ direction float dv = .5f * (Math.Abs(dgs.DvDx) + Math.Abs(dgs.DvDy)); if (dv == 0.0f) dv = .01f; dgEval.Point = dgs.Point + dv * dgs.DpDv; dgEval.U = dgs.U; dgEval.V = dgs.V + dv; dgEval.Normal = Normal.Normalize((Normal) Vector.Cross(dgs.DpDu, dgs.DpDv) + dv * dgs.DnDv); float vDisplace = d.Evaluate(dgEval); float displace = d.Evaluate(dgs); // Compute bump-mapped differential geometry var dgBump = dgs.Clone(); dgBump.DpDu = dgs.DpDu + (uDisplace - displace) / du * (Vector)dgs.Normal + displace * (Vector)dgs.DnDu; dgBump.DpDv = dgs.DpDv + (vDisplace - displace) / dv * (Vector)dgs.Normal + displace * (Vector)dgs.DnDv; dgBump.Normal = (Normal) Vector.Normalize(Vector.Cross(dgBump.DpDu, dgBump.DpDv)); if (dgs.Shape.ReverseOrientation ^ dgs.Shape.TransformSwapsHandedness) dgBump.Normal *= -1.0f; // Orient shading normal to match geometric normal dgBump.Normal = Normal.FaceForward(dgBump.Normal, dgGeom.Normal); return dgBump; }
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); }
public override Bsdf GetBsdf(DifferentialGeometry dgGeom, DifferentialGeometry dgShading) { // Allocate _BSDF_, possibly doing bump mapping with _bumpMap_ var dgs = (_bumpMap != null) ? Bump(_bumpMap, dgGeom, dgShading) : dgShading; var bsdf = new Bsdf(dgs, dgGeom.Normal); // Evaluate textures for _MatteMaterial_ material and allocate BRDF Spectrum r = Spectrum.Clamp(_kd.Evaluate(dgs)); float sig = MathUtility.Clamp(_sigma.Evaluate(dgs), 0.0f, 90.0f); if (!r.IsBlack) { if (sig == 0.0f) bsdf.Add(new Lambertian(r)); else bsdf.Add(new OrenNayar(r, sig)); } return bsdf; }
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; }
public virtual DifferentialGeometry GetShadingGeometry( Transform objectToWorld, DifferentialGeometry dg) { return(dg); }
public virtual bool TryIntersect(Ray ray, out float tHit, out float rayEpsilon, out DifferentialGeometry dg) { throw new InvalidOperationException("Unimplemented Shape.TryIntersect() method called."); }
public override Bssrdf GetBssrdf(DifferentialGeometry dg, Transform objectToWorld) { var dgs = _shape.GetShadingGeometry(objectToWorld, dg); return _material.GetBssrdf(dg, dgs); }
public abstract Bsdf GetBsdf(DifferentialGeometry dgGeom, DifferentialGeometry dgShading);
public virtual DifferentialGeometry GetShadingGeometry( Transform objectToWorld, DifferentialGeometry dg) { return dg; }
public virtual Bssrdf GetBssrdf(DifferentialGeometry dgGeom, DifferentialGeometry dgShading) { return null; }
public abstract Bssrdf GetBssrdf(DifferentialGeometry dg, Transform objectToWorld);
public override Bssrdf GetBssrdf(DifferentialGeometry dg, Transform objectToWorld) { return null; }
public override Bssrdf GetBssrdf(DifferentialGeometry dg, Transform objectToWorld) { throw new InvalidOperationException("Aggregate.GetBssrdf() method called; should have gone to GeometricPrimitive."); }
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 sphere hit float u = phi / _phiMax; float theta = MathUtility.Acos(MathUtility.Clamp(phit.Z / _radius, -1.0f, 1.0f)); float v = (theta - _thetaMin) / (_thetaMax - _thetaMin); // Compute sphere $\dpdu$ and $\dpdv$ float zradius = MathUtility.Sqrt(phit.X * phit.X + phit.Y * phit.Y); float invzradius = 1.0f / zradius; float cosphi = phit.X * invzradius; float sinphi = phit.Y * invzradius; var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0); var dpdv = (_thetaMax - _thetaMin) * new Vector(phit.Z * cosphi, phit.Z * sinphi, -_radius * MathUtility.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.0f); Vector d2Pdvv = -(_thetaMax - _thetaMin) * (_thetaMax - _thetaMin) * new Vector(phit.X, phit.Y, phit.Z); // 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); }
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 sphere hit float u = phi / _phiMax; float theta = MathUtility.Acos(MathUtility.Clamp(phit.Z / _radius, -1.0f, 1.0f)); float v = (theta - _thetaMin) / (_thetaMax - _thetaMin); // Compute sphere $\dpdu$ and $\dpdv$ float zradius = MathUtility.Sqrt(phit.X * phit.X + phit.Y * phit.Y); float invzradius = 1.0f / zradius; float cosphi = phit.X * invzradius; float sinphi = phit.Y * invzradius; var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0); var dpdv = (_thetaMax - _thetaMin) * new Vector(phit.Z * cosphi, phit.Z * sinphi, -_radius * MathUtility.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.0f); Vector d2Pdvv = -(_thetaMax - _thetaMin) * (_thetaMax - _thetaMin) * new Vector(phit.X, phit.Y, phit.Z); // 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; }