Commit: 6baa7a7eb787638661cddad0c4e7f78bd3a8fa5c
Author: Pascal Schoen
Date:   Mon Apr 18 15:21:32 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rB6baa7a7eb787638661cddad0c4e7f78bd3a8fa5c

disney diffuse is working correctly

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

M       intern/cycles/kernel/closure/bsdf_disney_diffuse.h
M       intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp
M       intern/cycles/kernel/shaders/stdosl.h

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

diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h 
b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
index 2b927c5..ff69a7a 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
@@ -1,3 +1,4 @@
+
 /*
  * Adapted from Open Shading Language with this license:
  *
@@ -30,12 +31,153 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __BSDF_DISNEY_DIFFUSE_
+#ifndef __BSDF_DISNEY_DIFFUSE_H__
 #define __BSDF_DISNEY_DIFFUSE_H__
 
+#include <cmath>
+
 CCL_NAMESPACE_BEGIN
 
-/* DIFFUSE */
+/* DISNEY DIFFUSE */
+
+ccl_device float diff_sqr(float a) {
+       return a * a;
+}
+
+ccl_device float3 diff_mon2lin(float3 x, float gamma) {
+       return make_float3(pow(x[0], gamma), pow(x[1], gamma), pow(x[2], 
gamma));
+}
+
+ccl_device float diff_GTR1(float NdotH, float a) {
+       if (a >= 1.0f) return 1.0f / M_PI_F;
+       float a2 = a*a;
+       float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH;
+       return (a2 - 1.0f) / (M_PI_F * log(a2) * t);
+}
+
+ccl_device float diff_GTR2(float NdotH, float a) {
+       float a2 = a * a;
+       float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH;
+       return a2 / (M_PI_F * t * t);
+}
+
+ccl_device float diff_GTR2_aniso(
+       float NdotH,
+       float HdotX,
+       float HdotY,
+       float ax,
+       float ay)
+{
+       return 1.0f / (M_PI_F * ax * ay * diff_sqr(diff_sqr(HdotX / ax) + 
diff_sqr(HdotY / ay)
+               + NdotH * NdotH));
+}
+
+ccl_device float diff_smithG_GGX(float Ndotv, float alphaG) {
+       float a = alphaG * alphaG;
+       float b = Ndotv * Ndotv;
+       return 1.0f / (Ndotv + sqrtf(a + b - a * b));
+}
+
+ccl_device float diff_SchlickFresnel(float u) {
+       float m = clamp(1.0f - u, 0.0f, 1.0f);
+       float m2 = m * m;
+       return m2 * m2 * m; // pow(m, 5)
+}
+
+ccl_device float3 diff_transform_to_local(const float3& v, const float3& n,
+       const float3& x, const float3& y)
+{
+       return make_float3(dot(v, x), dot(v, n), dot(v, y));
+}
+
+ccl_device float3 diff_mix(float3 x, float3 y, float a) {
+       return x * (1.0f - a) + y * a;
+}
+
+ccl_device float diff_mix(float x, float y, float a) {
+       return x * (1.0f - a) + y * a;
+}
+
+/* structures */
+struct DisneyDiffuseBRDFParams {
+       // brdf parameters
+       float3 m_base_color;
+       float m_subsurface;
+       float m_roughness;
+       float m_sheen;
+       float m_sheen_tint;
+
+       // color correction
+       float m_withNdotL;
+       float m_brightness;
+       float m_gamma;
+       float m_exposure;
+       float m_mon2lingamma;
+
+       // precomputed values
+       float3 m_cdlin, m_ctint, m_csheen;
+       float m_cdlum;
+       float m_weights[4];
+       bool m_withNdotL_b;
+
+       void precompute_values() {
+               m_cdlin = diff_mon2lin(m_base_color, m_mon2lingamma); 
//make_float3(1.0f, 0.795f, 0.0f));
+               m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * 
m_cdlin[2]; // luminance approx.
+
+               m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : 
make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
+               m_csheen = diff_mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, 
m_sheen_tint);
+
+               m_gamma = clamp(m_gamma, 0.0f, 5.0f);
+               m_exposure = clamp(m_exposure, -6.0f, 6.0f);
+               m_withNdotL_b = (m_withNdotL > 0.5f);
+       }
+};
+
+typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams;
+
+/* brdf */
+ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc,
+       const DisneyDiffuseBRDFParams *params, float3 N, float3 V, float3 L,
+       float3 H, float *pdf)
+{
+       float NdotL = dot(N, L);
+       float NdotV = dot(N, V);
+
+    if (NdotL < 0 || NdotV < 0) {
+        *pdf = 0.0f;
+        return make_float3(0.0f, 0.0f, 0.0f);
+    }
+
+       float LdotH = dot(L, H);
+
+    float Fd = 0.0f;
+       float FL = diff_SchlickFresnel(NdotL), FV = diff_SchlickFresnel(NdotV);
+
+    if (params->m_subsurface != 1.0f) {
+           const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * params->m_roughness;
+           Fd = diff_mix(1.0f, Fd90, FL) * diff_mix(1.0f, Fd90, FV);
+    }
+
+    if (params->m_subsurface > 0.0f) {
+           float Fss90 = LdotH*LdotH * params->m_roughness;
+           float Fss = diff_mix(1.0f, Fss90, FL) * diff_mix(1.0f, Fss90, FV);
+           float ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f);
+        Fd = diff_mix(Fd, ss, params->m_subsurface);
+    }
+
+       float3 value = M_1_PI_F * Fd * params->m_cdlin;
+       *pdf = NdotL * M_1_PI_F * params->m_cdlum;
+
+       // sheen component
+       if (params->m_sheen != 0.0f) {
+           float FH = diff_SchlickFresnel(LdotH);
+
+               value += FH * params->m_sheen * params->m_csheen;
+               *pdf += (1.0f / M_2PI_F) * params->m_sheen;
+       }
+
+       return value;
+}
 
 ccl_device int bsdf_disney_diffuse_setup(ShaderClosure *sc)
 {
@@ -44,46 +186,168 @@ ccl_device int bsdf_disney_diffuse_setup(ShaderClosure 
*sc)
 }
 
 ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc,
-        float3 color, const float3 I, const float3 omega_in, float *pdf)
+       const DisneyDiffuseBRDFParams *params, const float3 I,
+       const float3 omega_in, float *pdf)
 {
-       float3 N = sc->N;
+       float3 N = normalize(sc->N);
+       float3 V = I; // outgoing
+       float3 L = omega_in; // incoming
+       float3 H = normalize(L + V);
+
+    if (dot(sc->N, omega_in) > 0.0f) {
+        float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, 
pdf);
+
+        value *= dot(N, L);
+
+        // brightness
+        value *= params->m_brightness;
 
-       float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
-       *pdf = cos_pi;
-       return make_float3(cos_pi * color[0], cos_pi * color[1], cos_pi * 
color[2]);
+        // exposure
+        value *= pow(2.0f, params->m_exposure);
+
+        // gamma
+        value[0] = pow(value[0], 1.0f / params->m_gamma);
+        value[1] = pow(value[1], 1.0f / params->m_gamma);
+        value[2] = pow(value[2], 1.0f / params->m_gamma);
+
+               return value;
+    }
+    else {
+        *pdf = 0.0f;
+        return make_float3(0.0f, 0.0f, 0.0f);
+    }
 }
 
-ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc,
-        float3 color, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, 
const float3 I, const float3 omega_in, float *pdf)
 {
        return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, float3 
color,
-        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)
+ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const 
DisneyDiffuseBRDFParams *params,
+       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)
 {
-       float3 N = sc->N;
+       float3 N = normalize(sc->N);
+
+       sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
+
+       if (dot(Ng, *omega_in) > 0) {
+               float3 V = I; // outgoing
+               float3 L = *omega_in; // incoming
+               float3 H = normalize(L + V);
+
+               float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, 
L, H, pdf);
+
+               if (params->m_withNdotL_b)
+                       value *= dot(N, L);
+
+               // brightness
+               value *= params->m_brightness;
+
+               // exposure
+               value *= pow(2.0f, params->m_exposure);
+
+               // gamma
+               value[0] = pow(value[0], 1.0f / params->m_gamma);
+               value[1] = pow(value[1], 1.0f / params->m_gamma);
+               value[2] = pow(value[2], 1.0f / params->m_gamma);
+
+               *eval = make_float3(value[0], value[1], value[2]);
+
+#ifdef __RAY_DIFFERENTIALS__
+               // TODO: find a better approximation for the diffuse bounce
+               *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+               *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+#endif
+       }
+       else {
+               *pdf = 0;
+       }
 
+       /*// we are viewing the surface from the right side - send a ray out 
with cosine
        // distribution over the hemisphere
-       sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+       sample_cos_hemisphere(-N, randu, randv, omega_in, pdf);
+       if(dot(Ng, *omega_in) < 0) {
+               float3 H = normalize(*omega_in - I);
+               *eval = calculate_disney_diffuse_brdf(sc, params, -N, -I, 
*omega_in, H, pdf);
+
+        // multiply with NdotL
+        //if (params->m_withNdotL_b)
+        //     *eval *= dot(N, L);
+
+        // brightness
+        *eval *= params->m_brightness;
+
+        // exposure
+        *eval *= pow(2.0f, params->m_exposure);
+
+        // gamma
+        (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma);
+        (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma);
+        (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma);
+               //*eval = make_float3(*pdf, *pdf, *pdf);
 
-       if(dot(Ng, *omega_in) > 0.0f) {
-               *eval = make_float3(*pdf * color[0], *pdf * color[1], *pdf * 
color[2]);
 #ifdef __RAY_DIFFERENTIALS__
                // TODO: find a better approximation for the diffuse bounce
-               *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
-               *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+               *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+               *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
 #endif
        }
-       else
-               *pdf = 0.0f;
+       else {
+               *pdf = 0;
+       }*/
+       return LABEL_DIFFUSE;
+
+       /*float3 N = normalize(sc->N);
+       float3 T = normalize(sc->T);
+       float3 X, Y;
+
+       float cos_theta, phi, theta, sin_phi, cos_phi;
+
+       make_orthonormals_tangent(N, T, &X, &Y);
+
+       phi = 2.0f * M_PI_F * randu;
+       theta = 2.0f * M_PI_F * randv;
+       cos_theta = cosf(theta);
+       sin_phi = sinf(phi);
+       cos_phi = cosf(phi);
+
+       float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
+       float3 H = normalize(sin_theta * cos_phi * X + sin_theta * sin_phi * Y 
+ cos_theta * N);
+
+       *omega_in = 2.0f * dot(I, H) * H - I;
 
-       return LABEL_REFLECT|LABEL_DIFFUSE;
+       float3 V = I; // outgoing
+       float3 L = *omega_in; // incoming
+
+       *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf);
+
+       // multiply with NdotL
+       //if (params->m_withNdotL_b)
+       //      *eval *= dot(N, L);
+
+       // brightness
+       *eval *= params->m_brightness;
+
+       // exposure
+       *eval *= pow(2.0f, params->m_exposure);
+
+       // gamma
+       (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma);
+       (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma);
+       (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma);
+
+#ifdef __RAY_DIFFERENTIALS__
+       *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
+       *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
+#endif
+
+       return LABEL_REFLECT|LABEL_DIFFUSE;*/
 }
 
 C

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