Replace an NDFs sample and pdf method with a data-driven numerical approximation.
More...
Inherits NDF.
template<typename NDF, size_t samplesTheta = 90, size_t samplesPhi = 1,
string_literal NAME = NDF::name + string_literal("_sampler")>
requires concepts::ndf<NDF>
class bbm::ndf::sampler< NDF, samplesTheta, samplesPhi, NAME >
Replace an NDFs sample and pdf method with a data-driven numerical approximation.
- Template Parameters
-
| NDF | = NDF for which to replace sample and pdf. |
| samplesTheta | = number of samples to take along the theta angle of the halfway vector (detault = 90). |
| samplesPhi | = number of phi angles to average theta samples over (default = 1). |
| NAME | = name of the NDF (default is NDF::name + '_sampler'). |
| void initialize |
( |
void |
| ) |
const |
|
inlineprivate |
initialize the data structures
Sample along the sqrt(theta) angle so that samples are more densely placed near the specular peak. Because a NDF is a decreasing function, we place the sample at the beginning of a sample 'bin'. We compensate the non-linear sampling by scaling the sample with a compensation factor. Because the weighting is increases, we sample at the end of the 'bin' to avoid missing important samples (i.e., max(f*g) < max(f)*max(g)).
| Vec3d sample |
( |
const Vec3d & |
, |
|
|
const Vec2d & |
xi, |
|
|
Mask |
mask = true |
|
) |
| const |
|
inline |
Sample the NDF.
- Parameters
-
| view | = view direction (ignored) |
| xi | = 2D uniform random variables in [0..1] range |
| Mask | = enable/disbale lanes |
- Returns
- A sampled microfacet normal.
To avoid discontunuities, we sample according to a linear interpolation of the discrete PDF. Linear interpolation is achieved by distributing the samples, given a discrete bin, according to a linear-tent distribution centered at the mid-point of the bin, and extending to the middle of the neighboring bins. At the edges (0 and Pi/2), we reflect samples that exceed the hemispherical bounds.