public override (Ray, RgbColor, float) SampleRay(Vector2 primaryPos, Vector2 primaryDir) { // Sample a direction from the scene to the background var dirSample = SampleDirection(primaryDir); // Sample a point on the unit disc var unitDiscPoint = SampleWarp.ToConcentricDisc(primaryPos); // And transform it to the scene spanning disc orthogonal to the selected direction Vector3 tangent, binormal; ShadingSpace.ComputeBasisVectors(dirSample.Direction, out tangent, out binormal); var pos = SceneCenter + SceneRadius * (dirSample.Direction // offset outside of the scene + tangent * unitDiscPoint.X // remap unit disc x coordinate + binormal * unitDiscPoint.Y); // remap unit disc y coordinate // Compute the pdf: uniform sampling of a disc with radius "SceneRadius" float discJacobian = SampleWarp.ToConcentricDiscJacobian(); float posPdf = discJacobian / (SceneRadius * SceneRadius); // Compute the final result var ray = new Ray { Origin = pos, Direction = -dirSample.Direction, MinDistance = 0 }; var weight = dirSample.Weight / posPdf; var pdf = posPdf * dirSample.Pdf; return(ray, weight, pdf); }
public override float RayPdf(Vector3 point, Vector3 direction) { float dirPdf = DirectionPdf(-direction); float discJacobian = SampleWarp.ToConcentricDiscJacobian(); float posPdf = discJacobian / (SceneRadius * SceneRadius); return(posPdf * dirPdf); }