Commit: 3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd
Author: Pascal Schoen
Date:   Fri Sep 16 08:47:56 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rB3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd

Fixed a bug in the Disney BSDF that caused specular reflections to be too
bright and diffuse is now reacting to the roughness again

- A normalization for the fresnel was missing which caused the specular
  reflections to become too bright for the single-scatter GGX
- The roughness value for the diffuse BSSRDF part has always been
  overwritten and thus always 0
- Also the performance for refractive materials with roughness=0.0 has
  been improved

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

M       intern/cycles/kernel/closure/bsdf_disney_specular.h
M       intern/cycles/kernel/closure/bsdf_microfacet.h
M       intern/cycles/kernel/closure/bsdf_reflection.h
M       intern/cycles/kernel/closure/bssrdf.h
M       intern/cycles/kernel/osl/osl_closures.cpp
M       intern/cycles/kernel/osl/osl_closures.h
M       intern/cycles/kernel/svm/svm_closure.h

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

diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h 
b/intern/cycles/kernel/closure/bsdf_disney_specular.h
index 7e8139f..b83bb29 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_specular.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h
@@ -35,34 +35,39 @@
 
 CCL_NAMESPACE_BEGIN
 
+typedef ccl_addr_space struct DisneySpecularExtra {
+       float3 T, baseColor, cspec0;
+       bool alpha_x, alpha_y, rough_g, ior;
+} DisneySpecularExtra;
+
 typedef ccl_addr_space struct DisneySpecularBsdf {
        SHADER_CLOSURE_BASE;
 
-       float specular, specularTint, roughness, metallic, anisotropic, 
alpha_x, alpha_y, rough_g;
-       float3 N, T;
-       float3 baseColor, cspec0;
+       float specular, specularTint, roughness, metallic, anisotropic;
+       float3 N;
+       DisneySpecularExtra *extra;
 } DisneySpecularBsdf;
 
 ccl_device int bsdf_disney_specular_setup(DisneySpecularBsdf *bsdf)
 {
-       float m_cdlum = 0.3f * bsdf->baseColor.x + 0.6f * bsdf->baseColor.y + 
0.1f * bsdf->baseColor.z; // luminance approx.
+       float m_cdlum = 0.3f * bsdf->extra->baseColor.x + 0.6f * 
bsdf->extra->baseColor.y + 0.1f * bsdf->extra->baseColor.z; // luminance approx.
 
-       float3 m_ctint = m_cdlum > 0.0f ? bsdf->baseColor / m_cdlum : 
make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
+       float3 m_ctint = m_cdlum > 0.0f ? bsdf->extra->baseColor / m_cdlum : 
make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
 
        float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - 
bsdf->specularTint) + m_ctint * bsdf->specularTint; // lerp(make_float3(1.0f, 
1.0f, 1.0f), m_ctint, sc->data2/*specularTint*/);
-       bsdf->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - 
bsdf->metallic) + bsdf->baseColor * bsdf->metallic; // 
lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, 
sc->data0/*metallic*/);
+       bsdf->extra->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - 
bsdf->metallic) + bsdf->extra->baseColor * bsdf->metallic; // 
lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, 
sc->data0/*metallic*/);
 
        float aspect = safe_sqrtf(1.0f - bsdf->anisotropic * 0.9f);
        float r2 = sqr(bsdf->roughness);
        
        /* ax */
-       bsdf->alpha_x = fmaxf(0.001f, r2 / aspect);
+       bsdf->extra->alpha_x = fmaxf(0.001f, r2 / aspect);
 
        /* ay */
-       bsdf->alpha_y = fmaxf(0.001f, r2 * aspect);
+       bsdf->extra->alpha_y = fmaxf(0.001f, r2 * aspect);
 
        /* rough_g */
-       bsdf->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f);
+       bsdf->extra->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f);
 
     bsdf->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID;
     return SD_BSDF|SD_BSDF_HAS_EVAL;
@@ -75,7 +80,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
 
        float3 N = bsdf->N;
 
-       if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f)
+       if (bsdf->extra->alpha_x*bsdf->extra->alpha_y <= 1e-7f)
                return make_float3(0.0f, 0.0f, 0.0f);
 
        float cosNO = dot(N, I);
@@ -84,10 +89,10 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
        if (cosNI > 0 && cosNO > 0) {
                /* get half vector */
                float3 m = normalize(omega_in + I);
-               float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
+               float alpha2 = bsdf->extra->alpha_x * bsdf->extra->alpha_y;
                float D, G1o, G1i;
 
-               if (bsdf->alpha_x == bsdf->alpha_y) {
+               if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) {
                        /* isotropic
                         * eq. 20: (F*G*D)/(4*in*on)
                         * eq. 33: first we calculate D(m) */
@@ -104,12 +109,12 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
                else {
                        /* anisotropic */
             float3 X, Y, Z = N;
-            make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+            make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y);
 
             // distribution
             float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
-            float slope_x = -local_m.x/(local_m.z*bsdf->alpha_x);
-            float slope_y = -local_m.y/(local_m.z*bsdf->alpha_y);
+            float slope_x = -local_m.x/(local_m.z*bsdf->extra->alpha_x);
+            float slope_y = -local_m.y/(local_m.z*bsdf->extra->alpha_y);
             float slope_len = 1 + slope_x*slope_x + slope_y*slope_y;
 
             float cosThetaM = local_m.z;
@@ -123,7 +128,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
             float cosPhiO = dot(I, X);
             float sinPhiO = dot(I, Y);
 
-            float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->alpha_x*bsdf->alpha_x) + 
(sinPhiO*sinPhiO)*(bsdf->alpha_y*bsdf->alpha_y);
+            float alphaO2 = 
(cosPhiO*cosPhiO)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + 
(sinPhiO*sinPhiO)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
             alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO;
 
             G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
@@ -132,7 +137,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
             float cosPhiI = dot(omega_in, X);
             float sinPhiI = dot(omega_in, Y);
 
-                       float alphaI2 = 
(cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + 
(sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y);
+                       float alphaI2 = 
(cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + 
(sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
             alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
 
             G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
@@ -144,7 +149,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const 
ShaderClosure *sc, con
                float common = D * 0.25f / cosNO;
 
         float FH = schlick_fresnel(dot(omega_in, m));
-               float3 F = bsdf->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 
1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH);
+               float3 F = bsdf->extra->cspec0 * (1.0f - FH) + 
make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, 
make_float3(1.0f, 1.0f, 1.0f), FH);
 
                float3 out = F * G * common;
 
@@ -181,25 +186,23 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
        if(cosNO > 0) {
                float3 X, Y, Z = N;
 
-               if (bsdf->alpha_x == bsdf->alpha_y)
+               if (bsdf->extra->alpha_x == bsdf->extra->alpha_y)
                        make_orthonormals(Z, &X, &Y);
                else
-                       make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+                       make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y);
 
                /* importance sampling with distribution of visible normals. 
vectors are
                 * transformed to local space before and after */
                float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
                float3 local_m;
-        float3 m;
                float G1o;
 
-               local_m = importance_sample_microfacet_stretched(local_I, 
bsdf->alpha_x, bsdf->alpha_y,
+               local_m = importance_sample_microfacet_stretched(local_I, 
bsdf->extra->alpha_x, bsdf->extra->alpha_y,
                            randu, randv, false, &G1o);
 
-               m = X*local_m.x + Y*local_m.y + Z*local_m.z;
+               float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z;
                float cosThetaM = local_m.z;
 
-               /* reflection or refraction? */
         float cosMO = dot(m, I);
 
         if(cosMO > 0) {
@@ -207,7 +210,7 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
             *omega_in = 2 * cosMO * m - I;
 
             if(dot(Ng, *omega_in) > 0) {
-                               if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 
1e-4f) {
+                               if (bsdf->extra->alpha_x*bsdf->extra->alpha_y 
<= 1e-7f) {
                     /* some high number for MIS */
                     *pdf = 1e6f;
                     *eval = make_float3(1e6f, 1e6f, 1e6f);
@@ -215,10 +218,10 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
                 else {
                     /* microfacet normal is visible to this ray */
                     /* eq. 33 */
-                                       float alpha2 = bsdf->alpha_x * 
bsdf->alpha_y;
+                                       float alpha2 = bsdf->extra->alpha_x * 
bsdf->extra->alpha_y;
                     float D, G1i;
 
-                                       if (bsdf->alpha_x == bsdf->alpha_y) {
+                                       if (bsdf->extra->alpha_x == 
bsdf->extra->alpha_y) {
                         float cosThetaM2 = cosThetaM * cosThetaM;
                         float cosThetaM4 = cosThetaM2 * cosThetaM2;
                         float tanThetaM2 = 1/(cosThetaM2) - 1;
@@ -232,8 +235,8 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
                     }
                     else {
                         /* anisotropic distribution */
-                                               float slope_x = -local_m.x / 
(local_m.z*bsdf->alpha_x);
-                                               float slope_y = -local_m.y / 
(local_m.z*bsdf->alpha_y);
+                                               float slope_x = -local_m.x / 
(local_m.z*bsdf->extra->alpha_x);
+                                               float slope_y = -local_m.y / 
(local_m.z*bsdf->extra->alpha_y);
                         float slope_len = 1 + slope_x*slope_x + 
slope_y*slope_y;
 
                         float cosThetaM = local_m.z;
@@ -249,7 +252,7 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
                         float cosPhiI = dot(*omega_in, X);
                         float sinPhiI = dot(*omega_in, Y);
 
-                                               float alphaI2 = 
(cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + 
(sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y);
+                                               float alphaI2 = 
(cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + 
(sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
                         alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
 
                         G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
@@ -259,8 +262,9 @@ ccl_device int bsdf_disney_specular_sample(const 
ShaderClosure *sc,
                     float common = (G1o * D) * 0.25f / cosNO;
                     *pdf = common;
 
-                                       float FH = 
schlick_fresnel(dot(*omega_in, m));
-                                       float3 F = bsdf->cspec0 * (1.0f - FH) + 
make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, 
make_float3(1.0f, 1.0f, 1.0f), FH);
+                                       float FH = 
fresnel_dielectric_cos(dot(*omega_in, m), bsdf->extra->ior);
+                                       //float FH = 
schlick_fresnel(dot(*omega_in, m));
+                                       float3 F = bsdf->extra->cspec0 * (1.0f 
- FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, 
make_float3(1.0f, 1.0f, 1.0f), FH);
 
                     *eval = G1i * common * F;
                 }
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h 
b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 9ab9b17..6c2f295 100644
--- a/i

@@ 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