Fermat
|
Composite BSDF class
The interaction between the top clearcoat layer and the inner layers below that is modeled approximately, computing only the Fresnel transmission factor to enter the clearcoat, but without modeling the change due to refraction of the input and output directions a la Weidlich and Wilkie. This is done because the approach from Weidlich and Wilkie simulates only first-order scattering, and results in dramatic energy loss for rough materials. It is also questionable whether that would be more correct, given that accounting for multiple-scattering through the various layers can be modeled without altering the final lobe directions, and while only changing the statistics of the inner layer distributions, as described in: "Efficient Rendering of Layered Materials using an Atomic Decomposition with Statistical Operators", Laurent Belcour - in ACM Transactions on Graphics, Association for Computing Machinery, 2018. While we plan to adopt the full machinery of the latter in the future, we currently just crudely approximate it.
The inner layers of the BSDF use Fresnel coefficients to determine how much light undergoes glossy reflection, and how much undergoes transmission. Part of the radiance transmitted from the upper glossy layer undergoes diffuse scattering. Again, the interaction between the glossy layer and the underlying diffuse layer is modeled in a simplified manner, as if the layer was infinitely thin and the diffusely reflected particles were not interacting again with the upper layer.
#include <bsdf.h>
Public Types | |
enum | ComponentIndex { kDiffuseReflectionIndex = 0u, kDiffuseTransmissionIndex = 1u, kGlossyReflectionIndex = 2u, kGlossyTransmissionIndex = 3u, kClearcoatReflectionIndex = 4u, kNumComponents = 5u } |
enum | ComponentType { kAbsorption = 0u, kDiffuseReflection = 0x1u, kDiffuseTransmission = 0x2u, kGlossyReflection = 0x4u, kGlossyTransmission = 0x8u, kClearcoatReflection = 0x10u, kDiffuseMask = 0x3u, kGlossyMask = 0xCu, kReflectionMask = 0x5u, kTransmissionMask = 0xAu, kAllComponents = 0xFFu } |
typedef cugar::LambertTransBsdf | diffuse_trans_component |
typedef cugar::LambertBsdf | diffuse_component |
typedef cugar::GGXSmithBsdf | glossy_component |
Public Methods | |
FERMAT_HOST_DEVICE | Bsdf () |
FERMAT_HOST_DEVICE | Bsdf (const Bsdf &bsdf) |
FERMAT_HOST_DEVICE | Bsdf (const TransportType transport, const RenderingContextView renderer, const MeshMaterial material, const float mollification_factor=1.0f, const float mollification_bias=0.0f, const float min_roughness=0.0f) |
FERMAT_HOST_DEVICE | Bsdf (const TransportType transport, const RenderingContextView renderer, const cugar::Vector3f diffuse, const cugar::Vector3f specular, const float roughness, const cugar::Vector3f diffuse_trans, const float opacity=1.0f, const float ior=1.0f) |
FERMAT_HOST_DEVICE const diffuse_trans_component & | diffuse_trans () const |
FERMAT_HOST_DEVICE const diffuse_component & | diffuse () const |
FERMAT_HOST_DEVICE const glossy_component & | glossy () const |
FERMAT_HOST_DEVICE const glossy_component & | glossy_trans () const |
FERMAT_HOST_DEVICE float | get_eta (const float NoV) const |
FERMAT_HOST_DEVICE float | get_inv_eta (const float NoV) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE cugar::Vector3f | f (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, const ComponentType components=kAllComponents) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | f (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, cugar::Vector3f *f) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | f_and_p (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, cugar::Vector3f *f, float *p, const cugar::SphericalMeasure measure=cugar::kProjectedSolidAngle, bool RR=true) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | f_and_p (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, cugar::Vector3f &f, float &p, const cugar::SphericalMeasure measure=cugar::kProjectedSolidAngle, const bool RR=true, const ComponentType components=kAllComponents) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE float | p (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, const cugar::SphericalMeasure measure=cugar::kProjectedSolidAngle, const bool RR=true, const ComponentType components=kAllComponents) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | sampling_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f V, float &diffuse_refl_prob, float &diffuse_trans_prob, float &glossy_refl_prob, float &glossy_trans_prob) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | sampling_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f V, float *w) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | normalize_sampling_weights (float *w_p, float &coat_reflection_prob, float &coat_transmission_prob, const bool RR, const ComponentType components=kAllComponents) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | fresnel_weights (const float VoH, const float eta, cugar::Vector3f &r_coeff, cugar::Vector3f &t_coeff) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | fresnel_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f V, const cugar::Vector3f L, cugar::Vector3f &r_coeff, cugar::Vector3f &t_coeff) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | inner_component_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f V, const cugar::Vector3f L, cugar::Vector3f &diffuse_refl_coeff, cugar::Vector3f &diffuse_trans_coeff, cugar::Vector3f &glossy_refl_coeff, cugar::Vector3f &glossy_trans_coeff) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | inner_component_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f V, const cugar::Vector3f L, cugar::Vector3f *w) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | component_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, cugar::Vector3f &Fc_1, cugar::Vector3f &Tc_1, cugar::Vector3f &Fc_2, cugar::Vector3f &Tc_2, cugar::Vector3f *w) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE void | component_weights (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, cugar::Vector3f *w) const |
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE bool | sample_component (const cugar::DifferentialGeometry &geometry, const float z[3], const cugar::Vector3f in, const ComponentType out_comp, cugar::Vector3f &out, float &out_p, float &out_p_proj, cugar::Vector3f &out_g, const bool evaluate_full_bsdf=false) const |
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE bool | sample (const cugar::DifferentialGeometry &geometry, const float z[3], const cugar::Vector3f in, ComponentType &out_comp, cugar::Vector3f &out, float &out_p, float &out_p_proj, cugar::Vector3f &out_g, bool RR=true, bool evaluate_full_bsdf=false, const ComponentType components=kAllComponents) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE bool | clearcoat_transmission (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, cugar::Vector3f &H, float &cos_theta_i, float &eta, cugar::Vector3f &Fc_1, cugar::Vector3f &Tc_1) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE float | compression_factor (const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o) const |
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE float | glossy_reflectance (const float cos_theta) const |
Static Public Methods | |
static FERMAT_HOST_DEVICE uint32 | component_count () |
static FERMAT_HOST_DEVICE uint32 | component_index (const ComponentType comp) |
static FERMAT_HOST_DEVICE ComponentType | component_mask (const ComponentIndex comp) |
Public Members | |
diffuse_component | m_diffuse |
diffuse_trans_component | m_diffuse_trans |
glossy_component | m_glossy |
glossy_component | m_glossy_trans |
cugar::Vector3f | m_fresnel |
cugar::Vector3f | m_reflectivity |
float | m_ior |
float | m_opacity |
float | m_clearcoat_ior |
const float * | m_glossy_reflectance |
TransportType | m_transport |
enum Bsdf::ComponentIndex |
component type indices
enum Bsdf::ComponentType |
component type bitmasks
|
inline |
constructor
|
inline |
copy constructor
|
inline |
constructor
|
inline |
constructor
|
inlinestatic |
return the number of components
|
inlinestatic |
return the 0-based index corresponding to a given component
|
inlinestatic |
return the bitmask corresponding to a given component
|
inline |
evaluate the component weights of all layers - including the clearcoat
|
inline |
evaluate the component weights of all layers - including the clearcoat
|
inline |
apply the radiance compression factor of (eta_t / eta_i)^2
|
inline |
return the diffuse reflection component
|
inline |
return the diffuse transmission component
|
inline |
evaluate the BSDF f(V,L)
geometry | the local differential geometry |
in | the incoming direction |
out | the outgoing direction |
components | the components to consider |
|
inline |
evaluate the BSDF f(V,L) separately for all components
|
inline |
evaluate the BSDF f(V,L) and its pdf p(V,L) in a single call
|
inline |
evaluate the BSDF f(V,L) and its p(V,L) in a single call
|
inline |
compute the Fresnel reflection and transmission weights
|
inline |
compute the Fresnel reflection and transmission weights
|
inline |
return the incident ior ratio
|
inline |
return the incident inverse ior ratio
|
inline |
return the glossy reflection component
|
inline |
return the glossy transmission component
|
inline |
deprecated evaluate the Fresnel weight for the glossy component - after the clearcoat
|
inline |
evaluate the component weights of the inner layers - after the clearcoat
|
inline |
normalize the sampling weights of the inner layers given the coat sampling probability
|
inline |
evaluate the total projected probability p(V,L) = p(L|V)
geometry | the local differential geometry |
w_i | the incoming direction |
w_o | the outgoing direction |
measure | the spherical measure to use |
RR | indicate whether to use Russian-Roulette or not |
|
inline |
sample an outgoing direction
geometry | the local differential geometry |
z | the incoming direction |
in | the incoming direction |
out_comp | the output component |
out | the outgoing direction |
out_p | the output solid angle pdf |
out_p_proj | the output projected solid angle pdf |
out_g | the output sample value = f/p_proj |
RR | indicate whether to use Russian-Roulette or not |
evaluate_full_bsdf | ndicate whether to evaluate the full BSDF, or just an unbiased estimate |
components | the components to consider |
|
inline |
sample a given component
geometry | the local differential geometry |
z | the input random numbers, relative to the given component |
in | the incoming direction |
out_comp | the given component |
out | the outgoing direction |
out_p | the output solid angle pdf |
out_p_proj | the output projected solid angle pdf |
out_g | the output sample value = f/p_proj |
RR | indicate whether to use Russian-Roulette or not |
evaluate_full_bsdf | ndicate whether to evaluate the full BSDF, or just an unbiased estimate |
components | the components to consider |
|
inline |
evaluate the sampling weights for the inner layers
|
inline |
evaluate the sampling weights for the inner layers