Commit: a2dd0c5fafdabe1573299170fb3be98a3e46d17a
Author: Pascal Schoen
Date:   Wed Oct 26 08:51:10 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rBa2dd0c5fafdabe1573299170fb3be98a3e46d17a

Fixed glossy reflections and refractions for low roughness values and
cleaned up the code.

For low roughness values, the reflections had some strange behavior.

===================================================================

M       intern/cycles/kernel/closure/bsdf_microfacet.h
M       intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
M       intern/cycles/kernel/closure/bsdf_reflection.h
M       intern/cycles/kernel/closure/bsdf_util.h
M       intern/cycles/kernel/svm/svm_closure.h

===================================================================

diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h 
b/intern/cycles/kernel/closure/bsdf_microfacet.h
index ecc37cd..57e3dae 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN
 
 typedef ccl_addr_space struct MicrofacetExtra {
        float3 color, cspec0;
-       bool use_fresnel, is_disney_clearcoat, initial_outside, 
only_refractions, only_reflections;
+       bool use_fresnel, is_disney_clearcoat;
 } MicrofacetExtra;
 
 typedef ccl_addr_space struct MicrofacetBsdf {
@@ -234,22 +234,21 @@ ccl_device_forceinline float3 microfacet_sample_stretched(
        return normalize(make_float3(-slope_x, -slope_y, 1.0f));
 } 
 
-/* Calculate the fresnel color which is a blend between white and the F0 color 
*/
-ccl_device_forceinline float3 fresnel_color(const MicrofacetBsdf *bsdf, float3 
L, float3 H) {
+/* Calculate the reflection color
+ *
+ * If fresnel is used, the color is an interpolation of the F0 color and white
+ * with respect to the fresnel
+ *
+ * Else it is simply white
+ */
+ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, 
float3 L, float3 H) {
     float3 F = make_float3(1.0f, 1.0f, 1.0f);
 
     if(bsdf->extra) {
         if(bsdf->extra->use_fresnel) {
-            /* Calculate the fresnel interpolation factor 
-             * The value from fresnel_dielectric_cos(...) has to be normalized 
because
-             * the cspec0 keeps the F0 color
-             */
             float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
-            float F0_norm = 1.0f / (1.0f - F0);
-            float FH = (fresnel_dielectric_cos(dot(L, H), bsdf->ior) - F0) * 
F0_norm;
 
-            /* Blend between white and a specular color with respect to the 
fresnel */
-            F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 
1.0f) * FH;
+            F = interpolate_fresnel_color(L, H, bsdf->ior, F0, 
bsdf->extra->cspec0);
         }
     }
 
@@ -409,13 +408,14 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const 
ShaderClosure *sc, cons
                        float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
                        D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + 
tanThetaM2) * (alpha2 + tanThetaM2));
 
-                       /* eq. 34: now calculate G1(i,m) and G1(o,m) */
                        if(bsdf->extra) {
                                if(bsdf->extra->is_disney_clearcoat) {
+                    /* the alpha value for clearcoat is a fixed 0.25 => alpha2 
= 0.25 * 0.25 */
                                        alpha2 = 0.0625f;
                 }
             }
 
+                       /* eq. 34: now calculate G1(i,m) and G1(o,m) */
                        G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * 
cosNO) / (cosNO * cosNO)));
                        G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * 
cosNI) / (cosNI * cosNI))); 
                }
@@ -461,7 +461,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const 
ShaderClosure *sc, cons
                /* eq. 20 */
                float common = D * 0.25f / cosNO;
 
-        float3 F = fresnel_color(bsdf, omega_in, m);
+        float3 F = reflection_color(bsdf, omega_in, m);
 
                float3 out = F * G * common;
 
@@ -529,12 +529,10 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const 
ShaderClosure *sc, con
         * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
        float common = D * (m_eta * m_eta) / (cosNO * Ht2);
 
-    float3 F = fresnel_color(bsdf, omega_in, Ht);
-
-       float3 out = G * fabsf(cosHI * cosHO) * common * F;
+       float out = G * fabsf(cosHI * cosHO) * common;
        *pdf = G1o * fabsf(cosHO * cosHI) * common;
 
-       return out;
+       return make_float3(out, out, out);
 }
 
 ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const 
ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, 
float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 
*domega_in_dy, float *pdf)
@@ -579,6 +577,14 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals 
*kg, const ShaderClosure
                                                /* some high number for MIS */
                                                *pdf = 1e6f;
                                                *eval = make_float3(1e6f, 1e6f, 
1e6f);
+
+                        /* if fresnel is used, calculate the color with 
reflection_color(...) */
+                                   if(bsdf->extra) {
+                            if(bsdf->extra->use_fresnel) {
+                                *pdf = 1.0f;
+                                *eval = reflection_color(bsdf, *omega_in, m);
+                            }
+                        }
                                        }
                                        else {
                                                /* microfacet normal is visible 
to this ray */
@@ -599,9 +605,11 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals 
*kg, const ShaderClosure
                                                        /* eq. 34: now 
calculate G1(i,m) */
                                                        if(bsdf->extra) {
                                                                
if(bsdf->extra->is_disney_clearcoat) {
-                                                                       // 
recalculate G1o
-                                                                       G1o = 2 
/ (1 + safe_sqrtf(1 + 0.0625f * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+                                    /* the alpha value for clearcoat is a 
fixed 0.25 => alpha2 = 0.25 * 0.25 */
                                                                        alpha2 
= 0.0625f;
+
+                                                                       /* 
recalculate G1o */
+                                                                       G1o = 2 
/ (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
                                                                }
                             }
 
@@ -637,7 +645,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals 
*kg, const ShaderClosure
                                                float common = (G1o * D) * 
0.25f / cosNO;
                                                *pdf = common;
 
-                        float3 F = fresnel_color(bsdf, *omega_in, m);
+                        float3 F = reflection_color(bsdf, *omega_in, m);
 
                                                *eval = G1i * common * F;
                                        }
@@ -701,12 +709,10 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals 
*kg, const ShaderClosure
                                        /* see eval function for derivation */
                                        float common = (G1o * D) * (m_eta * 
m_eta) / (cosNO * Ht2);
 
-                    float3 F = fresnel_color(bsdf, *omega_in, m);
-
-                                       float3 out = G1i * fabsf(cosHI * cosHO) 
* common * F;
+                                       float out = G1i * fabsf(cosHI * cosHO) 
* common;
                                        *pdf = cosHO * fabsf(cosHI) * common;
 
-                                       *eval = out;
+                                       *eval = make_float3(out, out, out);
                                }
                        }
                }
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h 
b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
index 076d371..efd0fae 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
@@ -83,16 +83,14 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
        else
                eval *= -lambda_r * beta(-lambda_r, shadowing_lambda+1.0f);
 
-       float3 eval2;
+       float3 eval_fresnel;
        float3 t_color = cspec0;
-       float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
+       float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
        float F0 = fresnel_dielectric_cos(1.0f, eta);
-       float F0_norm = 1.0f / (1.0f - F0);
        if(use_fresnel) {
-               float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wo)), 
eta) - F0) * F0_norm;
-               throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 
1.0f) * FH;
+        throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wo), 
eta, F0, cspec0);
 
-               eval2 = throughput2 * eval;
+               eval_fresnel = throughput_fresnel * eval;
        }
 #elif defined(MF_MULTI_DIFFUSE)
        /* Diffuse has no special closed form for the single scattering bounce 
*/
@@ -112,16 +110,14 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
                eval = make_float3(val, val, val);
        }
 
-       float3 eval2;
+       float3 eval_fresnel;
        float3 t_color = cspec0;
-       float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
+       float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
        float F0 = fresnel_dielectric_cos(1.0f, eta);
-       float F0_norm = 1.0f / (1.0f - F0);
        if(use_fresnel) {
-               float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wo)), 
eta) - F0) * F0_norm;
-               throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 
1.0f) * FH;
+        throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wo), 
eta, F0, cspec0);
 
-               eval2 = throughput2 * val;
+               eval_fresnel = throughput_fresnel * val;
        }
 #endif
 
@@ -155,7 +151,7 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
                        else
                                phase = mf_eval_phase_glass(wr, lambda_r, -wo, 
!wo_outside, alpha, 1.0f / eta);
 
-                       eval2 = throughput2 * phase * mf_G1(wo_outside ? wo : 
-wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
+                       eval_fresnel = throughput_fresnel * phase * 
mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), 
shadowing_lambda);
                }
 #endif
                if(order > 0) {
@@ -168,14 +164,14 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
                                phase = mf_eval_phase_glass(wr, lambda_r, -wo, 
!wo_outside, alpha, 1.0f/eta);
 
                        if(use_fresnel)
-                               eval2 += throughput2 * phase * mf_G1(wo_outside 
? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
+                               eval_fresnel += throughput_fresnel * phase * 
mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), 
shadowing_lambda);
 #elif defined(MF_MULTI_DIFFUSE)
                        phase = mf_eval_phase_diffuse(wo, wm);
 #else /* MF_MULTI_GLOSSY */
                        phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha, 
n, k) * throughput;
 
                        if(use_fresnel)
-                               eval2 += throughput2 * phase * mf_G1(wo_outside 
? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
+                               eval_fresnel += throughput_fresnel * phase * 
mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), 
shadowing_lambda);
 #endif
                        eval += throughput * phase * mf_G1(wo_outside? wo: -wo, 
mf_C1((outside == wo_outside)? hr: -hr), shadowing_lambda);
                }
@@ -192,14 +188,13 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
                        }
 
                        if(use_fresnel && !next_outside) {
-                               throughput2 *= color;
+                               throughput_fresnel *= color;
                        }
                        else if(use_fresnel) {
-                               float FH = (fresnel_dielectric_cos(dot(wi_prev, 
wm), eta) - F0) * F0_norm;
-                               t_color = cspec0 * (1.0f - FH) + 
make_float3(1.0f, 1.0f, 1.0f) * FH;
+                t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, 
cspec0);
 
                                if(order > 0)
-                                       throughput2 *= t_color;
+                                       throughput_fresnel *= t_color;
                        }
 #elif defined(MF_MULTI_DIFFUSE)
                        wr = mf_sample_phase_diffuse(wm,
@@ -207,14 +202,13 @@ ccl_device_forceinline float3 
MF_FUNCTION_FULL_NAME(mf_eval)(
                                                     
lcg_step_float_addrspace(lcg_state));
 #else /* MF_MULTI_

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to