This code implements the unitary BRDF model in the paper "A Model for Geometric Reflections from Gaussian Surfaces extended to Grazing Angles" (pdf - open access).
This is an idealised physically-based rendering model where every incoming ray is reflected somewhere (in the upper hemisphere), corresponding to a random walk initialised with the specular direction. The result is a model in-between that of an idealised flat reflector, and Lambertian scattering.
The model is parameterised by a single roughness value
The BRDF can be written as a series in Zernike polynomials,
where r and s are the reflected and specular directions, but in practice this is summed as the (faster converging) series
where the
The source code is provided as a C file along with an example python binding in lib.py.
From the cloned repository on a unix-like system you could try
makeand run the tests,
make testBoth the C and python interfaces are there to calculate the isotropic BRDF k>=0 indicates the maximum number of terms to include.
import numpy as np
import pylab as pl
from urdf.lib import brdf_iso_jacobi
N=300
# NxN grid of projected r
yr, xr = (np.mgrid[:N,:N] + 0.5) * (2 / (N-1)) - 1
# Projected r only within |r| <= 1
idx = np.flatnonzero((yr*yr+xr*xr).ravel()<1.0)
xr = xr.ravel()[idx]
yr = yr.ravel()[idx]
# Specular direction
theta = 30 * np.pi/180.0 # Angle from normal
xs = np.sin(theta)
ys = 0
# Gradient of surface deviations
sigma = 0.2
# BRDF
f = np.zeros(N*N)
f[idx] = brdf_iso_jacobi(xr,yr,xs,ys, sigma, kmax=10)
f = np.reshape(f, (N,N))
# Plot
pl.imshow(f)
pl.show()which should produce something like

All this is equivalent to running python examples\example.py
