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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs