Support Forum       G3D Web Page     
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
G3D::UniversalBSDF Class Reference


G3D's default description of how a surface reflects light (photons). More...

Inherits G3D::ReferenceCountedObject.

Public Member Functions

bool conservativelyHasTransparency () const
 If the lambertian channel potentially has non-unit alpha or the transmission channel is non-trivially non-zero, returns true. More...
 
float etaReflect () const
 $\eta_r$ for the material on the outside of this object (i.e. More...
 
float etaTransmit () const
 $\eta_t$ for the material on the inside of this object (i.e. More...
 
const Color3extinctionReflect () const
 $\kappa_r$ Extinction coefficient for the material on the outside; complex part of the index of refraction. More...
 
const Color3extinctionTransmit () const
 $\kappa_t$ Extinction coefficient for the material on the inside; complex part of the index of refraction. More...
 
const Component4glossy () const
 Packed factors affecting mirror and glossy reflection. More...
 
bool hasGlossy () const
 Return true if there is any glossy (non-Lambertian, non-mirror) reflection from this BSDF. More...
 
bool hasLambertian () const
 Return true if there is any Lambertian reflection from this BSDF. More...
 
bool hasMirror () const
 Return true if there is any mirror reflection from this BSDF. More...
 
bool hasReflection () const
 Return true if there is any Lambertian, mirror, or glossy reflection from this BSDF (not just mirror!) More...
 
bool isZero () const
 True if this absorbs all light. More...
 
const Component4lambertian () const
 Packed factors affecting the lambertian term. More...
 
virtual void setStorage (ImageStorage s) const
 Move or copy data to CPU or GPU. More...
 
const Component3transmissive () const
 $T_0$ : transmissivity More...
 

Static Public Member Functions

static shared_ptr< UniversalBSDFcreate (const Component4 &lambertian, const Component4 &glossy=Texture::zero(), const Component3 &transmissive=Texture::opaqueBlack(), float eta_transmit=1.0f, const Color3 &extinction_transmit=Color3::zero(), float eta_reflect=1.0f, const Color3 &extinction_reflect=Color3::zero())
 
static float packedGlossyNone ()
 The value that a non-glossy surface is packed as. More...
 
static float packedSpecularMirror ()
 The value that a mirror's glossy exponent (infinity) is packed as. More...
 
static float packGlossyExponent (float blinnPhongExponent)
 Maps a Blinn-Phong exponent to G3D engine smoothness. More...
 
static Color3 schlickFresnel (const Color3 &F0, float cos_i, float smoothness)
 Computes F_r, given the cosine of the angle of incidence and the reflectance at normal incidence. More...
 
static float smoothnessToBlinnPhongExponent (float g3dSmoothness)
 Maps a G3D engine smoothness value to a Blinn-Phong exponent. More...
 

Static Public Attributes

static float ignoreFloat
 

Protected Member Functions

 UniversalBSDF ()
 

Static Protected Member Functions

template<class T , class ... ArgTypes>
static shared_ptr< T > createShared (ArgTypes &&... args)
 Like std::make_shared, but works for protected constructors. More...
 

Protected Attributes

float m_eta_r
 $\eta_r$ For the material on the outside. More...
 
float m_eta_t
 $\eta_t$ For the material on the inside. More...
 
Color3 m_extinction_r
 
Color3 m_extinction_t
 $\kappa_t$ Extinction coefficient for the material on the inside; complex part of the index of refraction. More...
 
Component4 m_glossy
 Packed factors affecting mirror and glossy reflection. More...
 
Component4 m_lambertian
 Packed factors affecting the lambertian term. More...
 
Component3 m_transmissive
 $T_0$ : transmissivity More...
 

Detailed Description


G3D's default description of how a surface reflects light (photons).

This is an analytic energy-conserving Bidirectional Scattering Distribution Function (BSDF) with phenomenonlogically meaningful parameters. It comprises Lambertian reflection, Schlick's Fresnel approximation for glossy and mirror reflection, Sloan, Hoffman, and Lafortune's normalization of the Blinn-Phong glossy lobe, and transmission (without exponential extinction) terms. It is a extension of the isotropic version of Ashikhmin and Shirley's empirical BRDF http://www.cs.utah.edu/~shirley/papers/jgtbrdf.pdf .

The methods of this class are primarily used for photon mapping, ray tracing, and software rasterization. The G3D::UniversalMaterial class manages BSDFs for GPU rasterization.

A surface is the 2D boundary between two 3D volumes. BSDF works with single-sided surfaces, so it is assumed that for transparent materials there are two oppositely-oriented surfaces, typically with different BSDFs, at every such boundary. Thus there are two indices of refraction at a surface: one for the inside (side opposite the normal) and one for the outside.

The major routines are:

scatter()
getImpulses()
evaluate()

The material is parameterized by:

$\rho_{L0}$[UniversalBSDF::lambertian.rgb, UniversalMaterial::Specification::setLambertian]. Peak Lambertian (a.k.a. "diffuse surface color") reflectance, on [0, 1]. The actual reflectance applied at normal incidence is $(1 - F_0) * \rho_{L0}$
$T_0$[UniversalBSDF::transmissive, UniversalMaterial::Specification::setTransmissive]. Transmission modulation factor ("transparent color") for the entire volume, on [0, 1]; 0 for opaque surfaces. The actual transmission at normal incidence will be $(1 - F_0) * T_0$. This is a fast approximation. Use the extinction coefficients for true participating medium transmission.
$F_0$[UniversalBSDF::glossy.rgb, UniversalMaterial::Specification::setShininess]. Fresnel reflection at normal incidence (a.k.a. "glossy/glossy/reflection color") on [0, 1]
$\sigma$[UniversalBSDF::glossy.a, UniversalMaterial::Specification::setShininess] Surface shininess/smoothness (a.k.a. "shininess", "glossy exponent") 0 for purely Lambertian surfaces, packedGlossyMirror() / UniversalMaterial::Specification::setMirrorShininess() for perfect reflection, and values between packGlossyExponent(1) and packGlossyExponent(128) for glossy reflection. This is used to compute $s$, the exponent on the normalized Blinn-Phong lobe.
$\eta_\mathrm{i}$Index of refraction outside the material, i.e., on the same side as the normal (only used for surfaces with $\rho_t > 0$; for computing refraction angle, not used for Fresnel factor).
$\eta_\mathrm{o}$Index of refraction inside the material, i.e., opposite the normal (only used for surfaces with $\rho_t > 0$; for computing refraction angle, not used for Fresnel factor).

For energy conservation, choose $F_0 + (1 - F_0)T_0\leq 1$ and $\rho_{L0} + T_0 \leq 1$.

The following terminology for photon scattering is used in the G3D::UniversalMaterial::Settings and G3D::UniversalBSDF classes and their documentation:

(Departures from theory for artistic control: The direct shader always applies a glossy highlight with an exponent of 128 to mirror surfaces so that light sources produce highlights. Setting the Glossy/Mirror coefficient to zero for a transmissive surface guarantees no reflection, although real transmissive surfaces should always be reflective at glancing angles.)

The BSDF consists of four terms (at most three of which are non-zero): Lambertian, Glossy, Mirror, and Transmissive,

\[ f(\vec{\omega}_\mathrm{i}, \vec{\omega}_\mathrm{o}) = f_L + f_g + f_m + f_t \]

where

\begin{eqnarray} \nonumber f_L &=& \rho_{L0} \cdot \frac{F_L(\vec{\omega}_\mathrm{i})}{\pi} \\ \nonumber f_g &=& \left\{\begin{array}{ccc} F_r(\vec{\omega}_\mathrm{i}) \cdot \frac{s + 8}{8 \pi} \cdot \max(0, \vec{n} \cdot \vec{\omega}_\mathrm{h})^{s} && \mbox{\texttt{packGlossyExponent}}(0) < \sigma < \mbox{\texttt{packedGlossyMirror()}}\\ \\ 0~\mbox{sr}^{-1} & & \mbox{otherwise} \\ \end{array}\right.\\ \nonumber f_m &=& \left\{\begin{array}{ccc} F_r(\vec{\omega}_i) ~ \delta(\vec{\omega}_o, \vec{\omega}_m) ~/ ~(\vec{\omega}_i \cdot \vec{n}) && \sigma = \mbox{\texttt{packedGlossyMirror()}}\\ \\ 0~\mbox{sr}^{-1} & & \mbox{otherwise} \\ \end{array}\right.\\ \nonumber f_t &=& F_t(\vec{\omega}_i) ~ T_0 ~ \delta(\vec{\omega}_o, \vec{\omega}_t) ~ / ~(\vec{\omega}_i \cdot \vec{n}) \end{eqnarray}

All vectors point outward from the surface. Let

\begin{eqnarray} \nonumber \vec{\omega}_h &=& \langle \vec{\omega}_i + \vec{\omega}_o \rangle\\ \nonumber s &=& \mbox{\texttt{smoothnessToBlinnPhongExponent}}(\sigma)\\ \nonumber \vec{\omega}_m &=& 2 (\vec{\omega}_i \cdot \vec{n}) \vec{n} - \vec{\omega}_i\\ \nonumber \vec{\omega}_t &=& -\frac{\eta_i}{\eta_t}(\vec{\omega}_i - (\vec{\omega}_i \cdot \vec{n}) \vec{n}) - \vec{n} \sqrt{1-\left( \frac{\eta_i}{\eta_t} \right)^2(1 - \vec{\omega}_i \cdot \vec{n})^2}\\ \nonumber F_t(\vec{\omega}_i) &=& 1 - F_r(\vec{\omega}_i)\\ \nonumber F_L(\vec{\omega}_i) &=& 1 - F_r(\vec{\omega}_i)\\ \nonumber F_r(\vec{\omega}_i) &=& F_0 + (1 - F_0) (1 - \max(0, \vec{\omega}_i \cdot \vec{n}))^5 \end{eqnarray}

$F_r(\vec{\omega}_i)$ is the Fresnel mirror reflection coefficient, which is approximated by Schlick's method as shown above.

The $T_0$ factor is the only significant source of error in the BSDF. An accurate scatting function would transmit with probabilty $F_t$ and then attenuate the scattered photon based on the distance traveled through the translucent medium. The concession to applying a constant attenuation is a typical one in rendering, however.

UniversalBSDF is scheduled to be merged into G3D::UniversalMaterial in December 2012.

See also
G3D::UniversalMaterial, G3D::Component, G3D::BumpMap, G3D::Texture, G3D::Surfel

Constructor & Destructor Documentation

◆ UniversalBSDF()

G3D::UniversalBSDF::UniversalBSDF ( )
inlineprotected

Member Function Documentation

◆ conservativelyHasTransparency()

bool G3D::UniversalBSDF::conservativelyHasTransparency ( ) const

If the lambertian channel potentially has non-unit alpha or the transmission channel is non-trivially non-zero, returns true.

Used by the ArticulatedModel OBJ loader to detect meshes that should be made two-sided.

This does not force lazy loaded textures to load.

◆ create()

static shared_ptr<UniversalBSDF> G3D::UniversalBSDF::create ( const Component4 lambertian,
const Component4 glossy = Texture::zero(),
const Component3 transmissive = Texture::opaqueBlack(),
float  eta_transmit = 1.0f,
const Color3 extinction_transmit = Color3::zero(),
float  eta_reflect = 1.0f,
const Color3 extinction_reflect = Color3::zero() 
)
static

◆ createShared()

template<class T , class ... ArgTypes>
static shared_ptr<T> G3D::ReferenceCountedObject::createShared ( ArgTypes &&...  args)
inlinestaticprotectedinherited

Like std::make_shared, but works for protected constructors.

Call as createShared<myclass>.

◆ etaReflect()

float G3D::UniversalBSDF::etaReflect ( ) const
inline

$\eta_r$ for the material on the outside of this object (i.e.

side of the normal).

◆ etaTransmit()

float G3D::UniversalBSDF::etaTransmit ( ) const
inline

$\eta_t$ for the material on the inside of this object (i.e.

side opposite the normal).

◆ extinctionReflect()

const Color3& G3D::UniversalBSDF::extinctionReflect ( ) const
inline

$\kappa_r$ Extinction coefficient for the material on the outside; complex part of the index of refraction.

http://en.wikipedia.org/wiki/Complex_index_of_refraction#Dispersion_and_absorption

◆ extinctionTransmit()

const Color3& G3D::UniversalBSDF::extinctionTransmit ( ) const
inline

$\kappa_t$ Extinction coefficient for the material on the inside; complex part of the index of refraction.

http://en.wikipedia.org/wiki/Complex_index_of_refraction#Dispersion_and_absorption

◆ glossy()

const Component4& G3D::UniversalBSDF::glossy ( ) const
inline

Packed factors affecting mirror and glossy reflection.

  • rgb = $F_0$ : glossy scattering probability/Fresnel reflectance at normal incidence. This is dependent on eta, although the interface allows them to be set independently.
  • a = $s$ : smoothness

◆ hasGlossy()

bool G3D::UniversalBSDF::hasGlossy ( ) const

Return true if there is any glossy (non-Lambertian, non-mirror) reflection from this BSDF.

◆ hasLambertian()

bool G3D::UniversalBSDF::hasLambertian ( ) const

Return true if there is any Lambertian reflection from this BSDF.

◆ hasMirror()

bool G3D::UniversalBSDF::hasMirror ( ) const

Return true if there is any mirror reflection from this BSDF.

◆ hasReflection()

bool G3D::UniversalBSDF::hasReflection ( ) const
inline

Return true if there is any Lambertian, mirror, or glossy reflection from this BSDF (not just mirror!)

◆ isZero()

bool G3D::UniversalBSDF::isZero ( ) const
inline

True if this absorbs all light.

◆ lambertian()

const Component4& G3D::UniversalBSDF::lambertian ( ) const
inline

Packed factors affecting the lambertian term.

  • rgb = $\rho_L$ : lambertian scattering probability
  • a = coverage mask (mainly useful only for maps, not constants).

◆ packedGlossyNone()

static float G3D::UniversalBSDF::packedGlossyNone ( )
inlinestatic

The value that a non-glossy surface is packed as.

◆ packedSpecularMirror()

static float G3D::UniversalBSDF::packedSpecularMirror ( )
inlinestatic

The value that a mirror's glossy exponent (infinity) is packed as.

◆ packGlossyExponent()

static float G3D::UniversalBSDF::packGlossyExponent ( float  blinnPhongExponent)
inlinestatic

Maps a Blinn-Phong exponent to G3D engine smoothness.

◆ schlickFresnel()

static Color3 G3D::UniversalBSDF::schlickFresnel ( const Color3 F0,
float  cos_i,
float  smoothness 
)
inlinestatic

Computes F_r, given the cosine of the angle of incidence and the reflectance at normal incidence.

Uses smoothness as a masking term to keep rough surfaces from having too much Fresnel

◆ setStorage()

virtual void G3D::UniversalBSDF::setStorage ( ImageStorage  s) const
virtual

Move or copy data to CPU or GPU.

Called from G3DMaterial::setStorage().

◆ smoothnessToBlinnPhongExponent()

static float G3D::UniversalBSDF::smoothnessToBlinnPhongExponent ( float  g3dSmoothness)
inlinestatic

Maps a G3D engine smoothness value to a Blinn-Phong exponent.

Note that 0 = no glossy and 1 = mirror are handled specially by many shaders.

The maximum exponent is clamped to 20k to avoid numerical precision problems in downstream computations.

◆ transmissive()

const Component3& G3D::UniversalBSDF::transmissive ( ) const
inline

$T_0$ : transmissivity

Member Data Documentation

◆ ignoreFloat

float G3D::UniversalBSDF::ignoreFloat
static

◆ m_eta_r

float G3D::UniversalBSDF::m_eta_r
protected

$\eta_r$ For the material on the outside.

Referenced by etaReflect().

◆ m_eta_t

float G3D::UniversalBSDF::m_eta_t
protected

$\eta_t$ For the material on the inside.

Referenced by etaTransmit().

◆ m_extinction_r

Color3 G3D::UniversalBSDF::m_extinction_r
protected

Referenced by extinctionReflect().

◆ m_extinction_t

Color3 G3D::UniversalBSDF::m_extinction_t
protected

$\kappa_t$ Extinction coefficient for the material on the inside; complex part of the index of refraction.

http://en.wikipedia.org/wiki/Complex_index_of_refraction#Dispersion_and_absorption

Referenced by extinctionTransmit().

◆ m_glossy

Component4 G3D::UniversalBSDF::m_glossy
protected

Packed factors affecting mirror and glossy reflection.

  • rgb = $F_0$ : glossy scattering probability/Fresnel reflectance at normal incidence. This is dependent on eta, although the interface allows them to be set independently.
  • a = $s/129$ : shininess (glossy exponent) divided by 129.

Referenced by glossy(), hasReflection(), and isZero().

◆ m_lambertian

Component4 G3D::UniversalBSDF::m_lambertian
protected

Packed factors affecting the lambertian term.

  • rgb = $\rho_L$ : lambertian scattering probability
  • a = coverage mask (mainly useful only for maps, not constants).

Referenced by hasReflection(), isZero(), and lambertian().

◆ m_transmissive

Component3 G3D::UniversalBSDF::m_transmissive
protected

$T_0$ : transmissivity

Referenced by isZero(), and transmissive().


documentation generated on Wed Nov 24 2021 08:02:01 using doxygen 1.8.15