|
|
|
|
|
|
return RoughnessToPerceptualRoughness(LinearVarianceToRoughness(v)); |
|
|
|
} |
|
|
|
|
|
|
|
/* Return the unpolarized version of the complete dielectric Fresnel equations |
|
|
|
* from `FresnelDielectric` without accounting for wave phase shift. |
|
|
|
*/ |
|
|
|
// TODO: we have this in BSDF lib, just verify |
|
|
|
// Return the unpolarized version of the complete dielectric Fresnel equations |
|
|
|
// from `FresnelDielectric` without accounting for wave phase shift. |
|
|
|
// TODO: verify we have in BSDF lib |
|
|
|
float FresnelUnpolarized(in float ct1, in float n1, in float n2) |
|
|
|
{ |
|
|
|
float cti = ct1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Helper function that parses the BSDFData object to generate the current layer's |
|
|
|
* statistics. |
|
|
|
* |
|
|
|
* TODO: R12 Should be replace by a fetch to FGD. |
|
|
|
* T12 should be multiplied by TIR. |
|
|
|
* (more like p8, T21 <- T21*TIR, R21 <- R21 + (1-TIR)*T21 ) |
|
|
|
*/ |
|
|
|
///Helper function that parses the BSDFData object to generate the current layer's |
|
|
|
// statistics. |
|
|
|
// |
|
|
|
// TODO: R12 Should be replace by a fetch to FGD. |
|
|
|
// T12 should be multiplied by TIR. |
|
|
|
// (more like p8, T21 <- T21*TIR, R21 <- R21 + (1-TIR)*T21 ) |
|
|
|
// |
|
|
|
void ComputeStatistics(in float cti, in int i, in BSDFData bsdfData, |
|
|
|
out float ctt, |
|
|
|
out float3 R12, out float3 T12, out float3 R21, out float3 T21, |
|
|
|
|
|
|
out float s_r21, out float s_t21, out float j21) |
|
|
|
{ |
|
|
|
|
|
|
|
/* Case of the dielectric coating */ |
|
|
|
// Case of the dielectric coating |
|
|
|
/* Update energy */ |
|
|
|
// Update energy |
|
|
|
R0 = FresnelUnpolarized(cti, n12, 1.0); // TODO |
|
|
|
R0 = FresnelUnpolarized(cti, n12, 1.0); |
|
|
|
R12 = R0; // sltodo: FGD |
|
|
|
R12 = R0; // TODO: FGD |
|
|
|
/* Update mean */ |
|
|
|
// Update mean |
|
|
|
float sti = sqrt(1.0 - Sq(cti)); |
|
|
|
float stt = sti / n12; |
|
|
|
if(stt <= 1.0f) { |
|
|
|
|
|
|
ctt = -1.0; |
|
|
|
} |
|
|
|
|
|
|
|
/* Update variance */ |
|
|
|
// Update variance |
|
|
|
s_r12 = RoughnessToLinearVariance(bsdfData.coatRoughness); |
|
|
|
s_t12 = RoughnessToLinearVariance(bsdfData.coatRoughness * 0.5 * abs((ctt*n12 - cti)/(ctt*n12))); |
|
|
|
j12 = (ctt/cti)*n12; |
|
|
|
|
|
|
j21 = 1.0/j12; |
|
|
|
|
|
|
|
/* Case of the media layer */ |
|
|
|
// Case of the media layer |
|
|
|
/* Update energy */ |
|
|
|
// Update energy |
|
|
|
/* Update mean */ |
|
|
|
// Update mean |
|
|
|
/* Update variance */ |
|
|
|
// Update variance |
|
|
|
s_r12 = 0.0; |
|
|
|
s_t12 = 0.0; |
|
|
|
j12 = 1.0; |
|
|
|
|
|
|
j21 = 1.0; |
|
|
|
|
|
|
|
/* Case of the dielectric / conductor base */ |
|
|
|
// Case of the dielectric / conductor base |
|
|
|
/* Update energy */ |
|
|
|
// Update energy |
|
|
|
R12 = F_Schlick(bsdfData.fresnel0, cti); |
|
|
|
T12 = 0.0; |
|
|
|
#ifdef VLAYERED_DIFFUSE_ENERGY_HACKED_TERM |
|
|
|
|
|
|
R21 = R12; |
|
|
|
T21 = T12; |
|
|
|
|
|
|
|
/* Update mean */ |
|
|
|
// Update mean |
|
|
|
/* Update variance */ |
|
|
|
// Update variance |
|
|
|
// |
|
|
|
// HACK: we will not propagate all needed last values, as we have 4, |
|
|
|
// but the adding cycle for the last layer can be shortcircuited for |
|
|
|
|
|
|
|
|
|
|
void ComputeAdding(float _cti, in BSDFData bsdfData, inout PreLightData preLightData, bool perLightCaller = false) |
|
|
|
{ |
|
|
|
/* Global Variables */ |
|
|
|
// Global Variables |
|
|
|
float cti = _cti; |
|
|
|
float3 R0i = float3(0.0, 0.0, 0.0), Ri0 = float3(0.0, 0.0, 0.0), |
|
|
|
T0i = float3(1.0, 1.0, 1.0), Ti0 = float3(1.0, 1.0, 1.0); |
|
|
|
|
|
|
float _s_r0m, s_r12, m_rr; // we will need these outside the loop for further calculations |
|
|
|
|
|
|
|
/* Iterate over the layers */ |
|
|
|
// Iterate over the layers |
|
|
|
/* Variables for the adding step */ |
|
|
|
// Variables for the adding step |
|
|
|
/* Layer specific evaluation of the transmittance, reflectance, variance */ |
|
|
|
// Layer specific evaluation of the transmittance, reflectance, variance |
|
|
|
/* Multiple scattering forms */ |
|
|
|
// Multiple scattering forms |
|
|
|
float3 denom = (float3(1.0, 1.0, 1.0) - Ri0*R12); //i = new layer, 0 = cumulative top (llab3.1 to 3.4) |
|
|
|
float3 m_R0i = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T0i*R12*Ti0) / denom; //(llab3.1) |
|
|
|
float3 m_Ri0 = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T21*Ri0*T12) / denom; //(llab3.2) |
|
|
|
|
|
|
m_rr = mean(m_Rr); |
|
|
|
|
|
|
|
/* Evaluate the adding operator on the energy */ |
|
|
|
// Evaluate the adding operator on the energy |
|
|
|
/* Scalar forms for the energy */ |
|
|
|
// Scalar forms for the energy |
|
|
|
/* Evaluate the adding operator on the normalized variance */ |
|
|
|
// Evaluate the adding operator on the normalized variance |
|
|
|
_s_r0m = s_ti0 + j0i*(s_t0i + s_r12 + m_rr*(s_r12+s_ri0)); |
|
|
|
float _s_r0i = (r0i*s_r0i + m_r0i*_s_r0m) / e_r0i; |
|
|
|
float _s_t0i = j12*s_t0i + s_t12 + j12*(s_r12 + s_ri0)*m_rr; |
|
|
|
|
|
|
_s_r0i = (e_r0i > 0.0) ? _s_r0i/e_r0i : 0.0; |
|
|
|
_s_ri0 = (e_ri0 > 0.0) ? _s_ri0/e_ri0 : 0.0; |
|
|
|
|
|
|
|
/* Store the coefficient and variance */ |
|
|
|
// Store the coefficient and variance |
|
|
|
if(m_r0i > 0.0) { |
|
|
|
// TODO: cleanup and check if unroll works, then need only top layer, can use an if |
|
|
|
// and the rest of the array is not needed |
|
|
|
|
|
|
preLightData.vLayerPerceptualRoughness[i] = 0.0; |
|
|
|
} |
|
|
|
|
|
|
|
/* Update energy */ |
|
|
|
// Update energy |
|
|
|
R0i = e_R0i; |
|
|
|
T0i = e_T0i; |
|
|
|
Ri0 = e_Ri0; |
|
|
|
|
|
|
/* Update mean */ |
|
|
|
// Update mean |
|
|
|
cti = ctt; |
|
|
|
|
|
|
|
// We need to escape this update on the last vlayer iteration, |
|
|
|
|
|
|
if( i < (NB_VLAYERS-1) ) |
|
|
|
{ |
|
|
|
/* Update variance */ |
|
|
|
// Update variance |
|
|
|
/* Update jacobian */ |
|
|
|
// Update jacobian |
|
|
|
j0i *= j12; |
|
|
|
ji0 *= j21; |
|
|
|
} |
|
|
|