| Description | uses | Classes, Interfaces, Objects and Records | Functions and Procedures | Types | Constants | Variables |
Random sampling of points (directions) on sphere and hemisphere.
Most of the implementation based on "Global Illumination Compendium" IV.B [http://www.cs.kuleuven.ac.be/˜phil/GI/]. (I will not mark it again at each function, "Global Illum..." was just used so often for this unit). Images in the "Global Illum..." may help to illustrate (better than any words) what's the meaning functions within this unit.
We use two ways to represent points on hemisphere:
Functions without "XYZ" suffix return vector of 2 floats = two angles, called phi and theta (in this order). Phi (in [0, 2*Pi]) is an angle from some chosen meridian. Theta (in [0, Pi/2] for hemisphere and [0, Pi] for sphere) is an angle from chosen vector pointing outward from the (hemi)sphere. Really, see images in "Global Illumination Compendium", they are probably much easier to understand than words :)
Sure, thinking about Phi and Theta as some angles related to some sphere is just a comfortable way to think about them. After all, they are just two numbers from some range and we sample them with some density, nothing more.
Functions with "XYZ" suffix return 3D point x, y, z.
(0, 0, 0) is the center of (hemi)sphere,
(0, 0, 1) is the chosen outward vector (i.e. Theta = 0 there),
(1, 0, 0) is the direction where Phi = 0 and Theta = Pi/2,
(0, 1, 0) is the direction where Phi = Pi/2 and Theta = Pi/2.
This is matching conventions in "Global Illumination Compendium", see there point (21).
Functions with Density <> Const return PdfValue for returned point, i.e. for density p(Theta) it's PfdValue = p(Result[1]). These functions try to calculate PdfValue smartly (often calculating PfdValue and calculating Result uses the same intermediate calculation, so we can save some computation). PdfValue is needed for importance sampling.
function PhiThetaToXYZ(const PhiTheta: TVector2Single; const SphereRadius: Single) :TVector3Single; overload; |
function PhiThetaToXYZ(const PhiTheta: TVector2Single; const SphereTheta0: TVector3Single): TVector3Single; overload; |
function RandomUnitHemispherePointDensityConst: TVector2Single; |
function RandomUnitHemispherePointDensityConstXYZ: TVector3Single; |
function RandomUnitHemispherePointDensityCosTheta( out PdfValue: Single): TVector2Single; |
function RandomUnitHemispherePointDensityCosThetaXYZ( out PdfValue: Single): TVector3Single; |
function RandomUnitHemispherePointDensityCosThetaExp(const n: Single; out PdfValue: Single): TVector2Single; |
function RandomUnitHemispherePointDensityCosThetaExpXYZ(const n: Single; out PdfValue: Single): TVector3Single; |
function PhiThetaToXYZ(const PhiTheta: TVector2Single; const SphereRadius: Single) :TVector3Single; overload; |
|
Convert from PhiTheta representation of (hemi)sphere direction to XYZ representation. See the beginning of this unit's documentation, SphereSampling, for more precise description of XYZ representation. |
function PhiThetaToXYZ(const PhiTheta: TVector2Single; const SphereTheta0: TVector3Single): TVector3Single; overload; |
|
Convert from PhiTheta representation of (hemi)sphere direction to XYZ representation. This is the more advanced version where you can freely specify which vector is the "main outside (hemi)sphere vector", SphereTheta0. Points with Theta = 0 are exactly on SphereTheta0. It is undefined where point like (Phi = 0, Theta = Pi/2) (or any other point with Theta <> 0) will be placed, i.e. it's not defined where's the "chosen meridian" for Phi = 0. However it's defined that this meridian will be determined only by SphereTheta0, and this is usually sufficient (since this makes sure that sampling and then converting to XYZ multiple points with the same SphereTheta0 will preserve sampled density). Note that the length of SphereTheta0 determines also the sphere radius. |
function RandomUnitHemispherePointDensityConst: TVector2Single; |
|
Random point (direction) on hemisphere, sampled with constant density (p(Theta) = 1/2*Pi). |
function RandomUnitHemispherePointDensityConstXYZ: TVector3Single; |
function RandomUnitHemispherePointDensityCosTheta( out PdfValue: Single): TVector2Single; |
|
Random point (direction) on hemisphere, sampled with density p(Theta) = cos(Theta)/Pi. |
function RandomUnitHemispherePointDensityCosThetaXYZ( out PdfValue: Single): TVector3Single; |
function RandomUnitHemispherePointDensityCosThetaExp(const n: Single; out PdfValue: Single): TVector2Single; |
|
Random point (direction) on hemisphere, sampled with density p(Theta) = (n+1) * (cos(Theta))ˆn / 2*Pi. |
function RandomUnitHemispherePointDensityCosThetaExpXYZ(const n: Single; out PdfValue: Single): TVector3Single; |