Composite BSDF class
- This class defines the Bidirectional Scattering Distribution Function employed throughout Fermat. At present time, this model is rather simple, and consists of five layered components only:
- a diffuse reflection component
- a diffuse transmission component
- a glossy reflection component layered on top of the diffuse layer
- a glossy transmission component layered on top of the diffuse layer
- a clearcoat layer on top of all of the above
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.
|
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 |
|