// Returns the solid angle subtended by the shape w.r.t. the reference // point p, given in world space. Some shapes compute this value in // closed-form, while the default implementation uses Monte Carlo // integration; the nSamples parameter determines how many samples are // used in this case. public virtual double SolidAngle(Point3D p, int nSamples = 512) { Interaction it = new Interaction(p, new Normal3D(), new Vector3D(), new Vector3D(0.0, 0.0, 1.0), 0.0, new MediumInterface()); double solidAngle = 0.0; for (int i = 0; i < nSamples; ++i) { Point2D u = new Point2D(PbrtMath.RadicalInverse(0, i), PbrtMath.RadicalInverse(1, i)); double pdf; Interaction pShape = Sample(it, u, out pdf); if (pdf > 0.0 && !IntersectP(new Ray(p, (pShape.P - p).ToVector3D(), 0.999))) { solidAngle += 1.0 / pdf; } } return(solidAngle / nSamples); }