Tools
BBM offers a few tools that can be helpful when implementing and validating a
BSDF model. All tools require that the user passes a bsdf in the form of a
string. The exact parser used depends on the BBM_DEFAULT_BSDF_IMPORTER
configuration variable.
renderSphere
Usage: ./renderSphere [bsdfmodel=<bsdf string>] [filename=<name>] [light=[0,0,1]] [width=512] [height=512]
Render an image of a sphere with a given bsdfmodel lit by a directional
light source. The image is saved to
the filename specified with filename=<name>. The supported image formats
are ppm and pfm (because they do not require an external library). The
light source direction is by default [0,0,1], but can be changed by
passing light=[x,y,z], with x, y, z the new direction. Similarly
width and height can be optionally set (default = 512).
plotBsdf
Usage: ./plotBsdf [bsdfmodel=<bsdf string>] [filename=<name>] [width=512] [height=256] [view=[0,0,1]] [samples=1] [scale=1] [maskZero] [plot=<eval|pdf|sample>]
Will plot a BSDF (specified by bsdfmodel) for a given view direction
(default is [0,0,1]) in latitude-longitude format (with resultion
(width, height)) and written to filename. You can select to plot the
eval, pdf, or sample function with an give average number of
samples per pixel. Optionally, you can scale the recorded pixel
values or mask pixels below the horizon to zero (maskZero).
For eval and pdf the tool will evaluate (the pdf of) the Bsdf for the
given view direction and the outdirection determined by the pixel location in
the latitute-longitude encoding.
For sample, the tools will generate samples * width * height samples
with the sample method, and plot add a unit value to the corresponding
pixel in the latitute-longitude encoding. If sample and pdf
correspond, then the images generated by both should be identical.
checkBsdf
This tool offers a number of numerical validations of the Bsdf.
Usage: ./checkBsdf [bsdfmodel=<bsdf string>] test=<test name> [test options]
+ test=reflectance [samples=100000] [theta=1] [importanceSampling]: compare the approximated reflectance method with a MC integration of the BSDF.
+ test=reciprocity [samples=100000]: checks if the BSDF is symmetric for 'samples' random dirctions.
+ test=adjoint [samples=100000]: checks if the adjoint BSDF is equal to the BSDF with in/out swapped.
+ test=pdf [samples=100000] [maxError=10] [checkBelowHorizon] [sampleSphere]: checks if the PDF >= 0, and the PDF returned by the sampling method matches the pdf from the pdf-method. Abort if the number of fails exceeds 'maxError'
+ test=pdfInt [samples=100000] [trials=10] [sampleSphere]: checks the integral (MC with 'samples' samples) of the PDF for 'trials' different directions.
+ test=sample [pdfSamples=4069] [samples=100000] [theta=10] [phi=20] [trials=10] [sampleSphere] [includeZeroPdfSamples]: perform Chi2 test on the sample vs the pdf method. The domain is subdivided in [theta x phi] bins, and for each bin we integrate the PDF using MC. A higher sampling rate might be needed for sharp BSDFs.
test=reflectance
Integrate the result from eval over the hemisphere of directions using
either cosine sampling (default) or importance sampling (enable by adding
importanceSampling) according to the sample method. The sampling is
performed for a number of fixed out directions regulary sampled in theta
(set number of theta samples with theta; default = one out direction:
[0,0,1]). The number of integration samples is set with samples. The
output looks like:
Using BSDF: Phong(albedo = [0.5, 0.5, 0.5], sharpness = 32.000000)
Reflectance test with 1 directions and 10000000 samples.
out = [0, 0, 1] => Estimate: [0.500794, 0.500794, 0.500794] vs. [0.5, 0.5, 0.5]
Indicating that the Monte Carlo integral was [0.500794, 0.500794,
0.500794] verssus [0.5, 0.5, 0.5] as computed by the (approximate)
reflectance method.
test=reciprocity
Draws samples number of random in and out directions and computes
the average and maximum difference between eval(in,out) and eval(out,
in) for both unit_t::Radiance as well as unit_t::Importance.
Ideally, the difference should be zero (except for certain BTDFs).
test=adjoint
Draws samples number of random in and out directions and compute
the difference between eval(in, out, unit_t::Radiance) and eval(out, in,
unit_t::Importance). Ideally, this should be zero (Walter et al.: footnote
page 5).
test=pdf
Checks basis properties of PDFs (i.e., positivity and sample.pdf == pdf)
for samples of random direction pairs (by default on the hemisphere, but
spherical sampling can be enabled with by passing sampleSphere). An error
will be thrown if more than maxError violations are found. Additionally,
if checkBelowHorizon is enabled, the method will check if the sample
method generates directions below the horizon (sampleSphere should not be
passed in that case).
test=pdfInt
For a 'trials number of random out direction on the hemisphere (or
sphere is sampleSphere is set), integrate the PDF using samples Monte
Carlo samples drawn uniformly over the sphere. Ideally, the integral should
be 1. However, if the BSDF is sharp specular, there will be significant Monte
Carlo noise due to the suboptimal sampling.
test=sample
Performs trials different white furnace test for randomly drawn out
direction on the hemisphere (or sphere if sampleSphere is set) by drawing
pdfSamples per bin (with theta times phi bins) on the incident
sphere. If includeZeroPdfSamples is set, then samples with a zero PDF are
included in the test. Note: currently this test is unreliable and not
recommended.