/// <summary> /// /// </summary> /// <param name="d"></param> /// <param name="dgGeom"></param> /// <param name="dgShading"></param> /// <param name="dgBump"></param> /// <returns></returns> public static async Task<DifferentialGeometry> BumpAsync (ITexture<double> d, DifferentialGeometry dgGeom, DifferentialGeometry dgShading) { var dgBump = new DifferentialGeometry (); var dgEval = new DifferentialGeometry (dgShading); var du = .5 * (Math.Abs (dgShading.dudx) + Math.Abs (dgShading.dudy)); if (du == 0.0) du = .01; dgEval.p = dgShading.p + du * dgShading.dpdu; dgEval.u = dgShading.u + du; dgEval.nn = null;// TODO var uDisplace = await d.EvaluateAsync (dgEval); var dv = .5 * (Math.Abs (dgShading.dvdx) + Math.Abs (dgShading.dvdy)); // var vDisplace = await d.EvaluateAsync (dgEval); var displace = await d.EvaluateAsync (dgShading); dgBump = new DifferentialGeometry (dgShading); dgBump.dpdu = dgShading.dpdu + (uDisplace - displace) / du * new Vector (dgShading.nn) + displace * new Vector (dgShading.dndu); dgBump.dpdv = dgShading.dpdv + (vDisplace - displace) / dv * new Vector (dgShading.nn) + displace * new Vector (dgShading.dndv); if (dgShading.Shape.ReverseOrientation ^ dgShading.Shape.TransformSwapsHandedness) dgBump.nn *= -1.0; dgBump.nn = Util.FaceForward (dgBump.nn, dgGeom.nn); return dgBump; }
/// <summary> /// /// </summary> /// <param name="dg"></param> /// <param name="objectToWorld"></param> /// <returns></returns> public abstract BSSRDF GetBSSRDF (DifferentialGeometry dg, Transform objectToWorld);
/// <summary> /// /// </summary> /// <param name="dg"></param> /// <param name="objectToWorld"></param> /// <returns></returns> public abstract Task<BSDF> GetBSDFAsync (DifferentialGeometry dg, Transform objectToWorld);
/// <summary> /// /// </summary> /// <param name="dgShading"></param> public DifferentialGeometry(DifferentialGeometry dgShading) { }
/// <summary> /// /// </summary> /// <param name="dgGeom"></param> /// <param name="dgShading"></param> /// <returns></returns> public abstract Task<BSDF> GetBSDFAsync (DifferentialGeometry dgGeom, DifferentialGeometry dgShading);
/// <summary> /// /// </summary> /// <param name="dgGeom"></param> /// <param name="dgShading"></param> /// <returns></returns> public abstract BSDF GetBSDF (DifferentialGeometry dgGeom, DifferentialGeometry dgShading);
public override bool Intersect(Ray r, out double tHit, out double rayEpsilon, DifferentialGeometry dg) { tHit = 0.0; rayEpsilon = 0.0; var ray = new Ray (); this.WorldToObject.Apply (r, ref ray); if (Math.Abs (ray.Direction.z) < 1e-7) return false; var thit = (height - ray.Origin.z) / ray.Direction.z; if (thit < ray.MinT || thit > ray.MaxT) return false; var phit = ray.Apply (thit); var dist2 = phit.x * phit.x + phit.y * phit.y; if (dist2 > radius * radius || dist2 < innerRadius * innerRadius) return false; var phi = Math.Atan2 (phit.y, phit.x); if (phi < 0) phi += 2.0 * Math.PI; if (phi > phiMax) return false; var u = phi / phiMax; var oneMinusV = ((Math.Sqrt (dist2) - innerRadius) / (radius - innerRadius)); var invOneMinusV = (oneMinusV > 0.0) ? (1.0 / oneMinusV) : 0.0; var v = 1.0 - oneMinusV; var dpdu = new Vector (-phiMax * phit.y, phiMax * phit.x, 0.0); var dpdv = new Vector (-phit.x * invOneMinusV, -phit.y * invOneMinusV, 0.0); dpdu *= phiMax * Util.InvTwoPI; dpdv *= (radius - innerRadius) / radius; var dndu = new Normal (0, 0, 0); var dndv = new Normal (0, 0, 0); var o2w = new Transform (this.ObjectToWorld); dg = new DifferentialGeometry (o2w.Apply (phit), null, null, o2w.Apply (dndu), o2w.Apply (dndv), u, v, this); tHit = thit; rayEpsilon = 5e-4 * tHit; return true; }
/// <summary> /// Checks if the shape intersects the ray /// </summary> /// <param name="ray">The ray to test against</param> /// <param name="tHit">If it intersects, the time where the ray was hit</param> /// <param name="rayEpsilon">The sharpness of the hit</param> /// <param name="dg">The differential geometry at the point of intersection</param> /// <returns>True if it intersects</returns> public virtual bool Intersect (Ray ray, out double tHit, out double rayEpsilon, DifferentialGeometry dg) { throw new NotImplementedException (); }
/// <summary> /// Computes the propability distribution function at the given point /// </summary> /// <param name="p">The point to check against</param> /// <param name="wi">The out vector</param> /// <returns>The propability distribution function</returns> public virtual double Pdf (Point p, Vector wi) { var dgLight = new DifferentialGeometry (); var ray = new Ray (p, wi, 1e-3); ray.Depth = -1; double thit, rayEpsilon; if (!this.Intersect (ray, out thit, out rayEpsilon, dgLight)) return 0.0; var pdf = Util.DistanceSquared (p, ray.Apply (thit)) / (Util.AbsDot (dgLight.nn, -wi) * this.Area); if (double.IsInfinity (pdf)) pdf = 0.0; return pdf; }