diff --git a/include/slg/materials/materialdefs_funcs_generic.cl b/include/slg/materials/materialdefs_funcs_generic.cl index e454930d0..176347ba0 100644 --- a/include/slg/materials/materialdefs_funcs_generic.cl +++ b/include/slg/materials/materialdefs_funcs_generic.cl @@ -160,6 +160,7 @@ OPENCL_FORCE_INLINE float SchlickDistribution_G(const float roughness, const flo } OPENCL_FORCE_INLINE float GetPhi(const float a, const float b) { + if ((a < DEFAULT_EPSILON_MIN) || (b < DEFAULT_EPSILON_MIN)) return 0.f; return M_PI_F * .5f * sqrt(a * b / (1.f - a * (1.f - b))); } @@ -254,13 +255,13 @@ OPENCL_FORCE_INLINE float3 SchlickBSDF_CoatingSampleF(const float3 ks, const float cosWH = dot(fixedDir, wh); *sampledDir = 2.f * cosWH * wh - fixedDir; - if ((fabs((*sampledDir).z) < DEFAULT_COS_EPSILON_STATIC) || (fixedDir.z * (*sampledDir).z < 0.f)) + if ((fabs((*sampledDir).z) < DEFAULT_COS_EPSILON_STATIC)) return BLACK; const float coso = fabs(fixedDir.z); const float cosi = fabs((*sampledDir).z); - *pdf = specPdf / (4.f * cosWH); + *pdf = specPdf / (4.f * fabs (cosWH)); if (*pdf <= 0.f) return BLACK; diff --git a/include/slg/materials/materialdefs_funcs_glossy2.cl b/include/slg/materials/materialdefs_funcs_glossy2.cl index 391cbb0d0..dec433ef1 100644 --- a/include/slg/materials/materialdefs_funcs_glossy2.cl +++ b/include/slg/materials/materialdefs_funcs_glossy2.cl @@ -76,19 +76,6 @@ OPENCL_FORCE_INLINE void Glossy2Material_Evaluate(__global const Material* restr const float3 kdVal = Texture_GetSpectrumValue(material->glossy2.kdTexIndex, hitPoint TEXTURES_PARAM); const float3 baseF = Spectrum_Clamp(kdVal) * M_1_PI_F * fabs(lightDir.z); - if (eyeDir.z <= 0.f) { - // Back face: no coating - - const float directPdfW = fabs(sampledDir.z * M_1_PI_F); - const BSDFEvent event = DIFFUSE | REFLECT; - const float3 result = baseF; - - EvalStack_PushFloat3(result); - EvalStack_PushBSDFEvent(event); - EvalStack_PushFloat(directPdfW); - - return; - } // Front face: coating+base const BSDFEvent event = GLOSSY | REFLECT; @@ -132,7 +119,7 @@ OPENCL_FORCE_INLINE void Glossy2Material_Evaluate(__global const Material* restr const float3 S = FresnelSchlick_Evaluate(ks, fabs(dot(sampledDir, H))); const float3 coatingF = SchlickBSDF_CoatingF(ks, roughness, anisotropy, material->glossy2.multibounce, - fixedDir, sampledDir); + fixedDir, sampledDir); // Blend in base layer Schlick style // assumes coating bxdf takes fresnel factor S into account @@ -161,25 +148,6 @@ OPENCL_FORCE_INLINE void Glossy2Material_Sample(__global const Material* restric const float3 kdVal = Texture_GetSpectrumValue(material->glossy2.kdTexIndex, hitPoint TEXTURES_PARAM); - if (fixedDir.z <= 0.f) { - // Back Face - float pdfW; - const float3 sampledDir = -1.f * CosineSampleHemisphereWithPdf(u0, u1, &pdfW); - if (fabs(CosTheta(sampledDir)) < DEFAULT_COS_EPSILON_STATIC) { - MATERIAL_SAMPLE_RETURN_BLACK; - } - - const BSDFEvent event = DIFFUSE | REFLECT; - const float3 result = Spectrum_Clamp(kdVal); - - EvalStack_PushFloat3(result); - EvalStack_PushFloat3(sampledDir); - EvalStack_PushFloat(pdfW); - EvalStack_PushBSDFEvent(event); - - return; - } - const float3 ksVal = Texture_GetSpectrumValue(material->glossy2.ksTexIndex, hitPoint TEXTURES_PARAM); float3 ks = ksVal; const float i = Texture_GetFloatValue(material->glossy2.indexTexIndex, hitPoint TEXTURES_PARAM); @@ -192,8 +160,8 @@ OPENCL_FORCE_INLINE void Glossy2Material_Sample(__global const Material* restric const float nuVal = Texture_GetFloatValue(material->glossy2.nuTexIndex, hitPoint TEXTURES_PARAM); const float nvVal = Texture_GetFloatValue(material->glossy2.nvTexIndex, hitPoint TEXTURES_PARAM); - const float u = clamp(nuVal, 1e-9f, 1.f); - const float v = clamp(nvVal, 1e-9f, 1.f); + const float u = clamp(nuVal, 1e-5f, 1.f); + const float v = clamp(nvVal, 1e-5f, 1.f); const float u2 = u * u; const float v2 = v * v; const float anisotropy = (u2 < v2) ? (1.f - u2 / v2) : u2 > 0.f ? (v2 / u2 - 1.f) : 0.f; @@ -207,18 +175,13 @@ OPENCL_FORCE_INLINE void Glossy2Material_Sample(__global const Material* restric float basePdf, coatingPdf; float3 baseF, coatingF; if (passThroughEvent < wBase) { - // Sample base BSDF (Matte BSDF) - baseF = Spectrum_Clamp(kdVal); - if (Spectrum_IsBlack(baseF)) { - MATERIAL_SAMPLE_RETURN_BLACK; - } sampledDir = (signbit(fixedDir.z) ? -1.f : 1.f) * CosineSampleHemisphereWithPdf(u0, u1, &basePdf); - if (fabs(CosTheta(sampledDir)) < DEFAULT_COS_EPSILON_STATIC) { + if (fabs(sampledDir.z) < DEFAULT_COS_EPSILON_STATIC) { MATERIAL_SAMPLE_RETURN_BLACK; } - baseF *= basePdf; + baseF = Spectrum_Clamp (kdVal) * M_1_PI_F * fabs(sampledDir.z); // Evaluate coating BSDF (Schlick BSDF) coatingF = SchlickBSDF_CoatingF(ks, roughness, anisotropy, material->glossy2.multibounce, @@ -232,7 +195,7 @@ OPENCL_FORCE_INLINE void Glossy2Material_Sample(__global const Material* restric MATERIAL_SAMPLE_RETURN_BLACK; } - const float absCosSampledDir = fabs(CosTheta(sampledDir)); + const float absCosSampledDir = fabs(sampledDir.z); if (absCosSampledDir < DEFAULT_COS_EPSILON_STATIC) { MATERIAL_SAMPLE_RETURN_BLACK; } @@ -241,7 +204,7 @@ OPENCL_FORCE_INLINE void Glossy2Material_Sample(__global const Material* restric // Evaluate base BSDF (Matte BSDF) basePdf = absCosSampledDir * M_1_PI_F; - baseF = Spectrum_Clamp(kdVal) * basePdf; + baseF = Spectrum_Clamp(kdVal) * M_1_PI_F * absCosSampledDir; } const BSDFEvent event = GLOSSY | REFLECT; diff --git a/src/slg/materials/glossy2.cpp b/src/slg/materials/glossy2.cpp index 62c08173c..1ad54b5f3 100644 --- a/src/slg/materials/glossy2.cpp +++ b/src/slg/materials/glossy2.cpp @@ -49,18 +49,6 @@ Spectrum Glossy2Material::Evaluate(const HitPoint &hitPoint, const Vector &localSampledDir = hitPoint.fromLight ? localEyeDir : localLightDir; const Spectrum baseF = Kd->GetSpectrumValue(hitPoint).Clamp(0.f, 1.f) * INV_PI * fabsf(localLightDir.z); - if (localEyeDir.z <= 0.f) { - // Back face: no coating - - if (directPdfW) - *directPdfW = fabsf(localSampledDir.z * INV_PI); - - if (reversePdfW) - *reversePdfW = fabsf(localFixedDir.z * INV_PI); - - *event = DIFFUSE | REFLECT; - return baseF; - } // Front face: coating+base *event = GLOSSY | REFLECT; @@ -81,34 +69,19 @@ Spectrum Glossy2Material::Evaluate(const HitPoint &hitPoint, const float roughness = u * v; if (directPdfW) { - if (localFixedDir.z < 0.f) { - // Backface - *directPdfW = fabsf(localSampledDir.z * INV_PI); - } else { - const float wCoating = SchlickBSDF_CoatingWeight(ks, localFixedDir); - const float wBase = 1.f - wCoating; - - *directPdfW = wBase * fabsf(localSampledDir.z * INV_PI) + - wCoating * SchlickBSDF_CoatingPdf(roughness, anisotropy, localFixedDir, localSampledDir); - } + const float wCoating = SchlickBSDF_CoatingWeight(ks, localFixedDir); + const float wBase = 1.f - wCoating; + + *directPdfW = wBase * fabsf(localSampledDir.z * INV_PI) + + wCoating * SchlickBSDF_CoatingPdf(roughness, anisotropy, localFixedDir, localSampledDir); } if (reversePdfW) { - if (localSampledDir.z < 0.f) { - // Backface - *reversePdfW = fabsf(localFixedDir.z * INV_PI); - } else { - const float wCoatingR = SchlickBSDF_CoatingWeight(ks, localSampledDir); - const float wBaseR = 1.f - wCoatingR; - - *reversePdfW = wBaseR * fabsf(localFixedDir.z * INV_PI) + - wCoatingR * SchlickBSDF_CoatingPdf(roughness, anisotropy, localSampledDir, localFixedDir); - } - } + const float wCoatingR = SchlickBSDF_CoatingWeight(ks, localSampledDir); + const float wBaseR = 1.f - wCoatingR; - if (localFixedDir.z < 0.f) { - // Backface, no coating - return baseF; + *reversePdfW = wBaseR * fabsf(localFixedDir.z * INV_PI) + + wCoatingR * SchlickBSDF_CoatingPdf(roughness, anisotropy, localSampledDir, localFixedDir); } // Absorption @@ -137,20 +110,6 @@ Spectrum Glossy2Material::Sample(const HitPoint &hitPoint, if (fabsf(localFixedDir.z) < DEFAULT_COS_EPSILON_STATIC) return Spectrum(); - if (localFixedDir.z <= 0.f) { - // Back face - *localSampledDir = -CosineSampleHemisphere(u0, u1, pdfW); - - const float absCosSampledDir = fabsf(localSampledDir->z); - if (absCosSampledDir < DEFAULT_COS_EPSILON_STATIC) - return Spectrum(); - *event = DIFFUSE | REFLECT; - if (hitPoint.fromLight) - return Kd->GetSpectrumValue(hitPoint) * fabsf(localFixedDir.z / absCosSampledDir); - else - return Kd->GetSpectrumValue(hitPoint); - } - Spectrum ks = Ks->GetSpectrumValue(hitPoint); const float i = index->GetFloatValue(hitPoint); if (i > 0.f) { @@ -159,15 +118,15 @@ Spectrum Glossy2Material::Sample(const HitPoint &hitPoint, } ks = ks.Clamp(0.f, 1.f); - const float u = Clamp(nu->GetFloatValue(hitPoint), 1e-9f, 1.f); - const float v = Clamp(nv->GetFloatValue(hitPoint), 1e-9f, 1.f); + const float u = Clamp(nu->GetFloatValue(hitPoint), 1e-5f, 1.f); + const float v = Clamp(nv->GetFloatValue(hitPoint), 1e-5f, 1.f); const float u2 = u * u; const float v2 = v * v; const float anisotropy = (u2 < v2) ? (1.f - u2 / v2) : u2 > 0.f ? (v2 / u2 - 1.f) : 0.f; const float roughness = u * v; // Coating is used only on the front face - const float wCoating = SchlickBSDF_CoatingWeight(ks, localFixedDir); + const float wCoating = SchlickBSDF_CoatingWeight (ks, localFixedDir); const float wBase = 1.f - wCoating; float basePdf, coatingPdf; @@ -247,29 +206,19 @@ void Glossy2Material::Pdf(const HitPoint &hitPoint, const float roughness = u * v; if (directPdfW) { - if (localFixedDir.z < 0.f) { - // Backface - *directPdfW = fabsf(localSampledDir.z * INV_PI); - } else { - const float wCoating = SchlickBSDF_CoatingWeight(ks, localFixedDir); - const float wBase = 1.f - wCoating; - - *directPdfW = wBase * fabsf(localSampledDir.z * INV_PI) + - wCoating * SchlickBSDF_CoatingPdf(roughness, anisotropy, localFixedDir, localSampledDir); - } + const float wCoating = SchlickBSDF_CoatingWeight(ks, localFixedDir); + const float wBase = 1.f - wCoating; + + *directPdfW = wBase * fabsf(localSampledDir.z * INV_PI) + + wCoating * SchlickBSDF_CoatingPdf(roughness, anisotropy, localFixedDir, localSampledDir); } if (reversePdfW) { - if (localSampledDir.z < 0.f) { - // Backface - *reversePdfW = fabsf(localFixedDir.z * INV_PI); - } else { - const float wCoatingR = SchlickBSDF_CoatingWeight(ks, localSampledDir); - const float wBaseR = 1.f - wCoatingR; - - *reversePdfW = wBaseR * fabsf(localFixedDir.z * INV_PI) + - wCoatingR * SchlickBSDF_CoatingPdf(roughness, anisotropy, localSampledDir, localFixedDir); - } + const float wCoatingR = SchlickBSDF_CoatingWeight(ks, localSampledDir); + const float wBaseR = 1.f - wCoatingR; + + *reversePdfW = wBaseR * fabsf(localFixedDir.z * INV_PI) + + wCoatingR * SchlickBSDF_CoatingPdf(roughness, anisotropy, localSampledDir, localFixedDir); } } diff --git a/src/slg/materials/material.cpp b/src/slg/materials/material.cpp index 072ac377d..e6f6222fa 100644 --- a/src/slg/materials/material.cpp +++ b/src/slg/materials/material.cpp @@ -423,6 +423,7 @@ float slg::SchlickDistribution_G(const float roughness, const Vector &localFixed } static float GetPhi(const float a, const float b) { + if ((a < DEFAULT_EPSILON_MIN) || (b < DEFAULT_EPSILON_MIN)) return 0.f; return M_PI * .5f * sqrtf(a * b / (1.f - a * (1.f - b))); } @@ -506,13 +507,13 @@ Spectrum slg::SchlickBSDF_CoatingSampleF(const bool fromLight, const Spectrum ks const float cosWH = Dot(localFixedDir, wh); *localSampledDir = 2.f * cosWH * wh - localFixedDir; - if ((fabsf(localSampledDir->z) < DEFAULT_COS_EPSILON_STATIC) || (localFixedDir.z * localSampledDir->z < 0.f)) + if ((fabsf (localSampledDir->z) < DEFAULT_COS_EPSILON_STATIC)) return Spectrum(); const float coso = fabsf(localFixedDir.z); const float cosi = fabsf(localSampledDir->z); - *pdf = specPdf / (4.f * cosWH); + *pdf = specPdf / (4.f * fabs (cosWH)); if (*pdf <= 0.f) return Spectrum();