Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf.h')
-rw-r--r--intern/cycles/kernel/closure/bsdf.h805
1 files changed, 400 insertions, 405 deletions
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 246cc8290d5..fbda52d74c4 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -70,7 +70,11 @@ ccl_device_inline float bsdf_get_roughness_squared(ccl_private const ShaderClosu
* Yining Karl Li and Brent Burley. */
ccl_device_inline float bump_shadowing_term(float3 Ng, float3 N, float3 I)
{
- float g = safe_divide(dot(Ng, I), dot(N, I) * dot(Ng, N));
+ const float cosNI = dot(N, I);
+ if (cosNI < 0.0f) {
+ Ng = -Ng;
+ }
+ float g = safe_divide(dot(Ng, I), cosNI * dot(Ng, N));
/* If the incoming light is on the unshadowed side, return full brightness. */
if (g >= 1.0f) {
@@ -99,15 +103,22 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl
return val;
}
+ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc,
+ const float3 omega_in)
+{
+ return dot(sc->N, omega_in) < 0.0f;
+}
+
ccl_device_inline int bsdf_sample(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
- ccl_private differential3 *domega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ ccl_private float2 *sampled_roughness,
+ ccl_private float *eta)
{
/* For curves use the smooth normal, particularly for ribbons the geometric
* normal gives too much darkening otherwise. */
@@ -116,119 +127,45 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
-#ifdef __SVM__
+#if defined(__SVM__) || defined(__OSL__)
case CLOSURE_BSDF_OREN_NAYAR_ID:
- label = bsdf_oren_nayar_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
# ifdef __OSL__
case CLOSURE_BSDF_PHONG_RAMP_ID:
- label = bsdf_phong_ramp_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_phong_ramp_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- label = bsdf_diffuse_ramp_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
# endif
case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
+ *sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
+ *sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = zero_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
@@ -236,169 +173,65 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_microfacet_ggx_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- label = bsdf_microfacet_ggx_glass_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_microfacet_ggx_glass_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(kg,
- sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_microfacet_beckmann_sample(
+ kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- label = bsdf_ashikhmin_shirley_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_ashikhmin_shirley_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- label = bsdf_diffuse_toon_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
- label = bsdf_glossy_toon_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ // double check if this is valid
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- label = bsdf_hair_reflection_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_hair_reflection_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- label = bsdf_hair_transmission_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_hair_transmission_sample(
+ sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(
- kg, sc, sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
break;
-# ifdef __PRINCIPLED__
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- label = bsdf_principled_diffuse_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
+ label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
- label = bsdf_principled_sheen_sample(sc,
- Ng,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
- break;
-# endif /* __PRINCIPLED__ */
+ label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
+ *sampled_roughness = one_float2();
+ *eta = 1.0f;
+ break;
#endif
default:
label = LABEL_NONE;
@@ -420,11 +253,12 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
const float frequency_multiplier =
kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
- *eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier);
+ const float cosNI = dot(*omega_in, sc->N);
+ *eval *= shift_cos_in(cosNI, frequency_multiplier);
}
if (label & LABEL_DIFFUSE) {
if (!isequal(sc->N, sd->N)) {
- *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in);
+ *eval *= bump_shadowing_term(sd->N, sc->N, *omega_in);
}
}
}
@@ -437,189 +271,350 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
return label;
}
+ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
+ ccl_private const ShaderClosure *sc,
+ ccl_private float2 *roughness,
+ ccl_private float *eta)
+{
+ bool refractive = false;
+ float alpha = 1.0f;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ alpha = phong_ramp_exponent_to_roughness(((ccl_private const PhongRampBsdf *)sc)->exponent);
+ *roughness = make_float2(alpha, alpha);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = zero_float2();
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = zero_float2();
+ // do we need to inverse eta??
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ *roughness = zero_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ *eta = bsdf->ior;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
+ } break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
+ *eta = 1.0f;
+ break;
+ }
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ // double check if this is valid
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
+ ((ccl_private HairBsdf *)sc)->roughness2);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
+ ((ccl_private HairBsdf *)sc)->roughness2);
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ alpha = ((ccl_private PrincipledHairBSDF *)sc)->m0_roughness;
+ *roughness = make_float2(alpha, alpha);
+ *eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+#endif
+ default:
+ *roughness = one_float2();
+ *eta = 1.0f;
+ break;
+ }
+}
+
+ccl_device_inline int bsdf_label(const KernelGlobals kg,
+ ccl_private const ShaderClosure *sc,
+ const float3 omega_in)
+{
+ /* For curves use the smooth normal, particularly for ribbons the geometric
+ * normal gives too much darkening otherwise. */
+ int label;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ case CLOSURE_BSSRDF_BURLEY_ID:
+ case CLOSURE_BSSRDF_RANDOM_WALK_ID:
+ case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+# ifdef __OSL__
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+# endif
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ label = LABEL_TRANSMIT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ label = LABEL_TRANSMIT | LABEL_SINGULAR;
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ label = LABEL_TRANSMIT | LABEL_TRANSPARENT;
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_REFLECT | LABEL_SINGULAR :
+ LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_TRANSMIT | LABEL_SINGULAR :
+ LABEL_TRANSMIT | LABEL_GLOSSY;
+ break;
+ }
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
+ LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ if (bsdf_is_transmission(sc, omega_in))
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+ else
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
+ label = LABEL_REFLECT | LABEL_DIFFUSE;
+ break;
+#endif
+ default:
+ label = LABEL_NONE;
+ break;
+ }
+
+ /* Test if BSDF sample should be treated as transparent for background. */
+ if (label & LABEL_TRANSMIT) {
+ float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
+
+ if (threshold_squared >= 0.0f) {
+ if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
+ label |= LABEL_TRANSMIT_TRANSPARENT;
+ }
+ }
+ }
+ return label;
+}
+
#ifndef __KERNEL_CUDA__
ccl_device
#else
ccl_device_inline
#endif
- float3
+ Spectrum
bsdf_eval(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 omega_in,
- const bool is_transmission,
ccl_private float *pdf)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
- if (!is_transmission) {
- switch (sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ switch (sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval(sc, sd->I, omega_in, pdf);
+ break;
+#if defined(__SVM__) || defined(__OSL__)
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval(sc, sd->I, omega_in, pdf);
+ break;
# ifdef __OSL__
- case CLOSURE_BSDF_PHONG_RAMP_ID:
- eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ eval = bsdf_diffuse_ramp_eval(sc, sd->I, omega_in, pdf);
+ break;
# endif
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_V2_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_ggx_glass_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-# ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- eval = bsdf_principled_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
- eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-# endif /* __PRINCIPLED__ */
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ eval = bsdf_microfacet_ggx_glass_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ eval = bsdf_ashikhmin_shirley_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_TOON_ID:
+ eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_GLOSSY_TOON_ID:
+ eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+ eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_REFLECTION_ID:
+ eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
+ eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+ eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+ case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
+ eval = bsdf_principled_sheen_eval(sc, sd->I, omega_in, pdf);
+ break;
#endif
- default:
- break;
- }
- if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- if (!isequal(sc->N, sd->N)) {
- eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
- }
- }
- /* Shadow terminator offset. */
- const float frequency_multiplier =
- kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
- if (frequency_multiplier > 1.0f) {
- eval *= shift_cos_in(dot(omega_in, sc->N), frequency_multiplier);
- }
+ default:
+ break;
}
- else {
- switch (sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_V2_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_ggx_glass_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- eval = bsdf_diffuse_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- eval = bsdf_hair_transmission_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-# ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- eval = bsdf_principled_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
- case CLOSURE_BSDF_PRINCIPLED_SHEEN_V2_ID:
- eval = bsdf_principled_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-# endif /* __PRINCIPLED__ */
-#endif
- default:
- break;
+
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ if (!isequal(sc->N, sd->N)) {
+ eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
}
- if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
- if (!isequal(sc->N, sd->N)) {
- eval *= bump_shadowing_term(-sd->N, sc->N, omega_in);
- }
+ }
+
+ /* Shadow terminator offset. */
+ const float frequency_multiplier =
+ kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
+ if (frequency_multiplier > 1.0f) {
+ const float cosNI = dot(omega_in, sc->N);
+ if (cosNI >= 0.0f) {
+ eval *= shift_cos_in(cosNI, frequency_multiplier);
}
}
+
#ifdef WITH_CYCLES_DEBUG
kernel_assert(*pdf >= 0.0f);
kernel_assert(eval.x >= 0.0f && eval.y >= 0.0f && eval.z >= 0.0f);
@@ -630,7 +625,7 @@ ccl_device_inline
ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float roughness)
{
/* TODO: do we want to blur volume closures? */
-#ifdef __SVM__
+#if defined(__SVM__) || defined(__OSL__)
switch (sc->type) {
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: