[Bf-blender-cvs] [5ff8221] cycles_disney_bsdf_transmittance: Implemented the thin surface diffuse part.
Pascal Schoen
noreply at git.blender.org
Wed Dec 14 15:06:49 CET 2016
Commit: 5ff822140fc90fa85c453072dbc1f860d6e252ca
Author: Pascal Schoen
Date: Mon Nov 14 16:58:09 2016 +0100
Branches: cycles_disney_bsdf_transmittance
https://developer.blender.org/rB5ff822140fc90fa85c453072dbc1f860d6e252ca
Implemented the thin surface diffuse part.
===================================================================
M intern/cycles/blender/blender_shader.cpp
M intern/cycles/kernel/closure/bsdf.h
M intern/cycles/kernel/closure/bsdf_disney_diffuse.h
M intern/cycles/kernel/closure/bssrdf.h
M intern/cycles/kernel/kernel_subsurface.h
M intern/cycles/kernel/osl/osl_bssrdf.cpp
M intern/cycles/kernel/osl/osl_closures.cpp
M intern/cycles/kernel/shaders/node_disney_bsdf.osl
M intern/cycles/kernel/shaders/stdosl.h
M intern/cycles/kernel/svm/svm_closure.h
M intern/cycles/kernel/svm/svm_types.h
M intern/cycles/render/graph.cpp
M intern/cycles/render/nodes.cpp
M intern/cycles/render/nodes.h
M source/blender/editors/space_node/drawnode.c
M source/blender/makesdna/DNA_node_types.h
M source/blender/makesrna/intern/rna_nodetree.c
M source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c
===================================================================
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index cb50b74..6f6a4d0 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -528,6 +528,14 @@ static ShaderNode *add_node(Scene *scene,
disney->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
break;
}
+ switch (b_disney_node.surface_type()) {
+ case BL::ShaderNodeBsdfDisney::surface_type_THIN_SURFACE:
+ disney->surface_type = THIN_SURFACE;
+ break;
+ case BL::ShaderNodeBsdfDisney::surface_type_SOLID_SURFACE:
+ disney->surface_type = SOLID_SURFACE;
+ break;
+ }
node = disney;
}
else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index b7c53df..83e33c1 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -133,10 +133,15 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
label = bsdf_disney_diffuse_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ label = bsdf_disney_retro_reflection_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
label = bsdf_disney_sheen_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
@@ -234,9 +239,13 @@ float3 bsdf_eval(KernelGlobals *kg,
eval = bsdf_hair_transmission_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
eval = bsdf_disney_diffuse_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ eval = bsdf_disney_retro_reflection_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
eval = bsdf_disney_sheen_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
@@ -309,9 +318,13 @@ float3 bsdf_eval(KernelGlobals *kg,
eval = bsdf_hair_transmission_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
eval = bsdf_disney_diffuse_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ eval = bsdf_disney_retro_reflection_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
eval = bsdf_disney_sheen_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
index ccb5966..a76be38 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
@@ -27,51 +27,174 @@ CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct DisneyDiffuseBsdf {
SHADER_CLOSURE_BASE;
- float roughness;
+ float roughness, flatness;
float3 N;
} DisneyDiffuseBsdf;
+
+/* DIFFUSE */
+
ccl_device float3 calculate_disney_diffuse_brdf(const DisneyDiffuseBsdf *bsdf,
- float3 N, float3 V, float3 L, float3 H, float *pdf)
+ float NdotL, float NdotV, float LdotH)
+{
+ float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
+ float Fd = (1.0f - 0.5f * FL) * (1.0f - 0.5f * FV);
+
+ float ss = 0.0f;
+ if(bsdf->flatness > 0.0f) {
+ // Based on Hanrahan-Krueger BRDF approximation of isotropic BSSRDF
+ // 1.25 scale is used to (roughly) preserve albedo
+ // Fss90 used to "flatten" retro-reflection based on roughness
+ float Fss90 = LdotH*LdotH * bsdf->roughness;
+ float Fss = (1.0f + (Fss90 - 1.0f) * FL) * (1.0f + (Fss90 - 1.0f) * FV);
+ ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f);
+ }
+
+ float value = Fd + (ss - Fd) * bsdf->flatness;
+ value *= M_1_PI_F * NdotL;
+
+ return make_float3(value, value, value);
+}
+
+ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+{
+ bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device int bsdf_disney_diffuse_transmit_setup(DisneyDiffuseBsdf *bsdf)
+{
+ bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+ const float3 omega_in, float *pdf)
+{
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+ if(m_transmittance)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 N = bsdf->N;
+
+ if(dot(N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
+ *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+ }
+ else {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+ const float3 omega_in, float *pdf)
{
- float NdotL = max(dot(N, L), 0.0f);
- float NdotV = max(dot(N, V), 0.0f);
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
- if(NdotL < 0 || NdotV < 0) {
+ if(!m_transmittance)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 N = bsdf->N;
+
+ if(dot(-N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
+ *pdf = fmaxf(dot(-N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+ }
+ else {
*pdf = 0.0f;
return make_float3(0.0f, 0.0f, 0.0f);
}
+}
+
+ccl_device int bsdf_disney_diffuse_sample(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)
+{
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+ float3 N = bsdf->N;
+
+ if(m_transmittance) {
+ sample_uniform_hemisphere(-N, randu, randv, omega_in, pdf);
+ }
+ else {
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ }
+
+ if(m_transmittance && dot(-Ng, *omega_in) > 0) {
+ float3 I_t = -((2 * dot(N, I)) * N - I);
+ float3 H = normalize(I_t + *omega_in);
+
+ *eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#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 if(!m_transmittance && dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(I + *omega_in);
+
+ *eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#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.0f;
+ }
- float LdotH = dot(L, H);
+ return (m_transmittance) ? LABEL_TRANSMIT|LABEL_DIFFUSE : LABEL_REFLECT|LABEL_DIFFUSE;
+}
+
+
+/* RETRO-REFLECTION */
+ccl_device float3 calculate_retro_reflection(const DisneyDiffuseBsdf *bsdf,
+ float NdotL, float NdotV, float LdotH)
+{
float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
- const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * bsdf->roughness;
- float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
+ float RR = 2.0f * bsdf->roughness * LdotH*LdotH;
+
+ float FRR = RR * (FL + FV + FL * FV * (RR - 1.0f));
- float value = M_1_PI_F * NdotL * Fd;
+ float value = M_1_PI_F * FRR * NdotL;
return make_float3(value, value, value);
}
-ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+ccl_device int bsdf_disney_retro_reflection_setup(DisneyDiffuseBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+ bsdf->type = CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID;
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_eval_reflect(const ShaderClosure *sc, const float3 I,
const float3 omega_in, float *pdf)
{
const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
if(dot(N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
- return calculate_disney_diffuse_brdf(bsdf, N, V, L, H, pdf);
+ return calculate_retro_reflection(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
}
else {
*pdf = 0.0f;
@@ -79,13 +202,13 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, cons
}
}
-ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_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,
+ccl_device int bsdf_disney_retro_reflection_sample(const ShaderClos
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list