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:
authorBrecht Van Lommel <brecht@blender.org>2022-09-22 21:03:24 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-09-27 16:56:28 +0300
commit6d19da0b2d468f099e0c1f56392ab8a1750d114f (patch)
tree7309b5ef31d5e42dca4e26e13b74bd6f223cba41
parentbd249eb4f37e65b2f4b3deef775bb136a2c234d1 (diff)
Cycles: BSDF eval refactor to remove separate reflection/refraction methods
Simplifies code overall to do it inside the eval function, most of the BSDFs already compute the dot product. The refactoring in bsdf_principled_hair_eval() was needed to avoid a HIP compiler bug. Cause is unclear, just changing the implementation enough is meant to sidestep it. Ref T92571, D15286
-rw-r--r--intern/cycles/kernel/closure/bsdf.h266
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h240
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h120
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h34
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h44
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h194
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h379
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h74
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h17
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h17
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_diffuse.h24
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_sheen.h27
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h17
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h17
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h53
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h17
-rw-r--r--intern/cycles/kernel/integrator/mnee.h2
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h12
-rw-r--r--intern/cycles/kernel/integrator/surface_shader.h16
20 files changed, 680 insertions, 916 deletions
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index d202018be9a..71af68aa80e 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -69,7 +69,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) {
@@ -98,6 +102,12 @@ 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,
@@ -264,11 +274,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);
}
}
}
@@ -491,7 +502,7 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
label = LABEL_TRANSMIT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
- if (is_transmission)
+ if (bsdf_is_transmission(sc, omega_in))
label = LABEL_TRANSMIT | LABEL_GLOSSY;
else
label = LABEL_REFLECT | LABEL_GLOSSY;
@@ -531,179 +542,104 @@ ccl_device_inline
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 omega_in,
- const bool is_transmission,
ccl_private float *pdf)
{
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;
+ 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_reflect(sc, sd->I, omega_in, pdf);
- break;
+ 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_CLEARCOAT_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_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(
- sc, sd->I, omega_in, pdf, &sd->lcg_state);
- 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;
- 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:
- eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
+ 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_CLEARCOAT_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_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ break;
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+ eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
+ 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:
+ 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;
-#if defined(__SVM__) || defined(__OSL__)
- 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_CLEARCOAT_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_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
- break;
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(
- sc, sd->I, omega_in, pdf, &sd->lcg_state);
- 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;
- 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:
- eval = bsdf_principled_sheen_eval_transmit(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);
}
- 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);
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index cfe1ced43f2..14a4094d485 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -39,11 +39,10 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
return 2.0f / (roughness * roughness) - 2.0f;
}
-ccl_device_forceinline Spectrum
-bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float3 N = bsdf->N;
@@ -53,70 +52,60 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
float out = 0.0f;
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || !(NdotI > 0.0f && NdotO > 0.0f)) {
*pdf = 0.0f;
return zero_spectrum();
}
- if (NdotI > 0.0f && NdotO > 0.0f) {
- NdotI = fmaxf(NdotI, 1e-6f);
- NdotO = fmaxf(NdotO, 1e-6f);
- float3 H = normalize(omega_in + I);
- float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
- float HdotN = fmaxf(dot(H, N), 1e-6f);
-
- /* pump from original paper
- * (first derivative disc., but cancels the HdotI in the pdf nicely) */
- float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI)));
- /* pump from d-brdf paper */
- /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */
-
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
-
- if (n_x == n_y) {
- /* isotropic */
- float e = n_x;
- float lobe = powf(HdotN, e);
- float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper). */
- *pdf = norm * lobe / HdotI;
+
+ NdotI = fmaxf(NdotI, 1e-6f);
+ NdotO = fmaxf(NdotO, 1e-6f);
+ float3 H = normalize(omega_in + I);
+ float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
+ float HdotN = fmaxf(dot(H, N), 1e-6f);
+
+ /* pump from original paper
+ * (first derivative disc., but cancels the HdotI in the pdf nicely) */
+ float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI)));
+ /* pump from d-brdf paper */
+ /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */
+
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+
+ if (n_x == n_y) {
+ /* isotropic */
+ float e = n_x;
+ float lobe = powf(HdotN, e);
+ float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper). */
+ *pdf = norm * lobe / HdotI;
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y;
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
+
+ float HdotX = dot(H, X);
+ float HdotY = dot(H, Y);
+ float lobe;
+ if (HdotN < 1.0f) {
+ float e = (n_x * HdotX * HdotX + n_y * HdotY * HdotY) / (1.0f - HdotN * HdotN);
+ lobe = powf(HdotN, e);
}
else {
- /* anisotropic */
- float3 X, Y;
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- float HdotX = dot(H, X);
- float HdotY = dot(H, Y);
- float lobe;
- if (HdotN < 1.0f) {
- float e = (n_x * HdotX * HdotX + n_y * HdotY * HdotY) / (1.0f - HdotN * HdotN);
- lobe = powf(HdotN, e);
- }
- else {
- lobe = 1.0f;
- }
- float norm = sqrtf((n_x + 1.0f) * (n_y + 1.0f)) / (8.0f * M_PI_F);
-
- out = NdotO * norm * lobe * pump;
- *pdf = norm * lobe / HdotI;
+ lobe = 1.0f;
}
+ float norm = sqrtf((n_x + 1.0f) * (n_y + 1.0f)) / (8.0f * M_PI_F);
+
+ out = NdotO * norm * lobe * pump;
+ *pdf = norm * lobe / HdotI;
}
return make_spectrum(out);
}
-ccl_device Spectrum bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x,
float n_y,
float randu,
@@ -146,81 +135,84 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
int label = LABEL_REFLECT | LABEL_GLOSSY;
float NdotI = dot(N, I);
- if (NdotI > 0.0f) {
+ if (!(NdotI > 0.0f)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
- float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
- float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
+ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
+ float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
- /* get x,y basis on the surface for anisotropy */
- float3 X, Y;
+ /* get x,y basis on the surface for anisotropy */
+ float3 X, Y;
+
+ if (n_x == n_y)
+ make_orthonormals(N, &X, &Y);
+ else
+ make_orthonormals_tangent(N, bsdf->T, &X, &Y);
- if (n_x == n_y)
- make_orthonormals(N, &X, &Y);
- else
- make_orthonormals_tangent(N, bsdf->T, &X, &Y);
-
- /* sample spherical coords for h in tangent space */
- float phi;
- float cos_theta;
- if (n_x == n_y) {
- /* isotropic sampling */
- phi = M_2PI_F * randu;
- cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+ /* sample spherical coords for h in tangent space */
+ float phi;
+ float cos_theta;
+ if (n_x == n_y) {
+ /* isotropic sampling */
+ phi = M_2PI_F * randu;
+ cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+ }
+ else {
+ /* anisotropic sampling */
+ if (randu < 0.25f) { /* first quadrant */
+ float remapped_randu = 4.0f * randu;
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
}
- else {
- /* anisotropic sampling */
- if (randu < 0.25f) { /* first quadrant */
- float remapped_randu = 4.0f * randu;
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- }
- else if (randu < 0.5f) { /* second quadrant */
- float remapped_randu = 4.0f * (.5f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F - phi;
- }
- else if (randu < 0.75f) { /* third quadrant */
- float remapped_randu = 4.0f * (randu - 0.5f);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = M_PI_F + phi;
- }
- else { /* fourth quadrant */
- float remapped_randu = 4.0f * (1.0f - randu);
- bsdf_ashikhmin_shirley_sample_first_quadrant(
- n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
- phi = 2.0f * M_PI_F - phi;
- }
+ else if (randu < 0.5f) { /* second quadrant */
+ float remapped_randu = 4.0f * (.5f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F - phi;
}
-
- /* get half vector in tangent space */
- float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
- float cos_phi = cosf(phi);
- float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
- float3 h = make_float3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
-
- /* half vector to world space */
- float3 H = h.x * X + h.y * Y + h.z * N;
- float HdotI = dot(H, I);
- if (HdotI < 0.0f)
- H = -H;
-
- /* reflect I on H to get omega_in */
- *omega_in = -I + (2.0f * HdotI) * H;
-
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
- /* Some high number for MIS. */
- *pdf = 1e6f;
- *eval = make_spectrum(1e6f);
- label = LABEL_REFLECT | LABEL_SINGULAR;
+ else if (randu < 0.75f) { /* third quadrant */
+ float remapped_randu = 4.0f * (randu - 0.5f);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = M_PI_F + phi;
}
- else {
- /* leave the rest to eval_reflect */
- *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
+ else { /* fourth quadrant */
+ float remapped_randu = 4.0f * (1.0f - randu);
+ bsdf_ashikhmin_shirley_sample_first_quadrant(
+ n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
+ phi = 2.0f * M_PI_F - phi;
}
}
+ /* get half vector in tangent space */
+ float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta));
+ float cos_phi = cosf(phi);
+ float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
+ float3 h = make_float3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
+
+ /* half vector to world space */
+ float3 H = h.x * X + h.y * Y + h.z * N;
+ float HdotI = dot(H, I);
+ if (HdotI < 0.0f)
+ H = -H;
+
+ /* reflect I on H to get omega_in */
+ *omega_in = -I + (2.0f * HdotI) * H;
+
+ if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_spectrum(1e6f);
+ label = LABEL_REFLECT | LABEL_SINGULAR;
+ }
+ else {
+ /* leave the rest to eval */
+ *eval = bsdf_ashikhmin_shirley_eval(sc, I, *omega_in, pdf);
+ }
+
return label;
}
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 9e68ea5d5e5..ac2183e0848 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -31,10 +31,10 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc;
float m_invsigma2 = bsdf->invsigma2;
@@ -42,46 +42,37 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderC
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
- if (cosNO > 0 && cosNI > 0) {
- float3 H = normalize(omega_in + I);
+ if (!(cosNO > 0 && cosNI > 0)) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float3 H = normalize(omega_in + I);
- if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float out = 0.25f * (D * G) / cosNO;
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
- *pdf = 0.5f * M_1_PI_F;
- return make_spectrum(out);
- }
+ float out = 0.25f * (D * G) / cosNO;
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
+ *pdf = 0.5f * M_1_PI_F;
+ return make_spectrum(out);
}
ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
@@ -101,41 +92,42 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
// distribution over the hemisphere
sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
- if (dot(Ng, *omega_in) > 0) {
- float3 H = normalize(*omega_in + I);
+ if (!(dot(Ng, *omega_in) > 0)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
+
+ float3 H = normalize(*omega_in + I);
- float cosNI = dot(N, *omega_in);
- float cosNO = dot(N, I);
- float cosNH = dot(N, H);
- float cosHO = fabsf(dot(I, H));
+ float cosNI = dot(N, *omega_in);
+ float cosNO = dot(N, I);
+ float cosNH = dot(N, H);
+ float cosHO = fabsf(dot(I, H));
- if (fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f) {
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
+ if (!(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
+ *pdf = 0.0f;
+ *eval = zero_spectrum();
+ return LABEL_NONE;
+ }
- float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
- float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
+ float cosNHdivHO = cosNH / cosHO;
+ cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
- float sinNH2 = 1 - cosNH * cosNH;
- float sinNH4 = sinNH2 * sinNH2;
- float cotangent2 = (cosNH * cosNH) / sinNH2;
+ float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
+ float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
- float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
- float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+ float sinNH2 = 1 - cosNH * cosNH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotangent2 = (cosNH * cosNH) / sinNH2;
- float power = 0.25f * (D * G) / cosNO;
+ float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
+ float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
+
+ float power = 0.25f * (D * G) / cosNO;
+
+ *eval = make_spectrum(power);
- *eval = make_spectrum(power);
- }
- else {
- *pdf = 0.0f;
- *eval = zero_spectrum();
- }
- }
- else {
- *pdf = 0.0f;
- *eval = zero_spectrum();
- }
return LABEL_REFLECT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index ec64c375666..c9c26754651 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -26,10 +26,10 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
@@ -39,15 +39,6 @@ ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *s
return make_spectrum(cos_pi);
}
-ccl_device Spectrum bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
@@ -81,19 +72,10 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index d7faf5c9e9a..e955ed00b92 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -47,25 +47,23 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug
{
}
-ccl_device Spectrum bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
- *pdf = cos_pi * M_1_PI_F;
- return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
-}
-
-ccl_device Spectrum bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- return zero_spectrum();
+ if (cos_pi >= 0.0f) {
+ *pdf = cos_pi * M_1_PI_F;
+ return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
+ }
+ else {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
}
ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index 69c05813982..a8ba4044758 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -37,12 +37,17 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
+ if (dot(bsdf->N, omega_in) < 0.0f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
@@ -84,30 +89,17 @@ ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderCl
return make_spectrum(*pdf);
}
-ccl_device Spectrum bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
+ if (dot(bsdf->N, omega_in) >= 0.0f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
float offset = bsdf->offset;
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index d0a44c65d52..857b3fbf3a6 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -56,13 +56,7 @@ ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
/* Remaps the given angle to [-pi, pi]. */
ccl_device_inline float wrap_angle(float a)
{
- while (a > M_PI_F) {
- a -= M_2PI_F;
- }
- while (a < -M_PI_F) {
- a += M_2PI_F;
- }
- return a;
+ return (a + M_PI_F) - M_2PI_F * floorf((a + M_PI_F) / M_2PI_F) - M_PI_F;
}
/* Logistic distribution function. */
@@ -271,76 +265,72 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
- float3 Y = float4_to_float3(bsdf->extra->geom);
+ const float3 Y = float4_to_float3(bsdf->extra->geom);
- float3 X = safe_normalize(sd->dPdu);
+ const float3 X = safe_normalize(sd->dPdu);
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
+ const float3 Z = safe_normalize(cross(X, Y));
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
- float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+ const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ const float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
+ const float sin_theta_o = wo.x;
+ const float cos_theta_o = cos_from_sin(sin_theta_o);
+ const float phi_o = atan2f(wo.z, wo.y);
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
+ const float sin_theta_t = sin_theta_o / bsdf->eta;
+ const float cos_theta_t = cos_from_sin(sin_theta_t);
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
+ const float sin_gamma_o = bsdf->extra->geom.w;
+ const float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ const float gamma_o = safe_asinf(sin_gamma_o);
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
+ const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ const float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ const float gamma_t = safe_asinf(sin_gamma_t);
- Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
Spectrum Ap[4];
float Ap_energy[4];
hair_attenuation(
kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
- float sin_theta_i = wi.x;
- float cos_theta_i = cos_from_sin(sin_theta_i);
- float phi_i = atan2f(wi.z, wi.y);
+ const float sin_theta_i = wi.x;
+ const float cos_theta_i = cos_from_sin(sin_theta_i);
+ const float phi_i = atan2f(wi.z, wi.y);
- float phi = phi_i - phi_o;
+ const float phi = phi_i - phi_o;
float angles[6];
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- Spectrum F;
- float F_energy;
- float Mp, Np;
-
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- F_energy = Ap_energy[0] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- F_energy += Ap_energy[1] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- F_energy += Ap_energy[2] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ Spectrum F = zero_spectrum();
+ float F_energy = 0.0f;
+
+ /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
+ for (int i = 0; i < 3; i++) {
+ const float Mp = longitudinal_scattering(angles[2 * i],
+ angles[2 * i + 1],
+ sin_theta_o,
+ cos_theta_o,
+ (i == 0) ? bsdf->m0_roughness :
+ (i == 1) ? 0.25f * bsdf->v :
+ 4.0f * bsdf->v);
+ const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
+ F += Ap[i] * Mp * Np;
+ F_energy += Ap_energy[i] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
/* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- F_energy += Ap_energy[3] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ {
+ const float Mp = longitudinal_scattering(
+ sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ const float Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
*pdf = F_energy;
return F;
@@ -363,35 +353,35 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
*sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
*eta = bsdf->eta;
- float3 Y = float4_to_float3(bsdf->extra->geom);
+ const float3 Y = float4_to_float3(bsdf->extra->geom);
- float3 X = safe_normalize(sd->dPdu);
+ const float3 X = safe_normalize(sd->dPdu);
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
- float3 Z = safe_normalize(cross(X, Y));
+ const float3 Z = safe_normalize(cross(X, Y));
- float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
+ const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
float2 u[2];
u[0] = make_float2(randu, randv);
u[1].x = lcg_step_float(&sd->lcg_state);
u[1].y = lcg_step_float(&sd->lcg_state);
- float sin_theta_o = wo.x;
- float cos_theta_o = cos_from_sin(sin_theta_o);
- float phi_o = atan2f(wo.z, wo.y);
+ const float sin_theta_o = wo.x;
+ const float cos_theta_o = cos_from_sin(sin_theta_o);
+ const float phi_o = atan2f(wo.z, wo.y);
- float sin_theta_t = sin_theta_o / bsdf->eta;
- float cos_theta_t = cos_from_sin(sin_theta_t);
+ const float sin_theta_t = sin_theta_o / bsdf->eta;
+ const float cos_theta_t = cos_from_sin(sin_theta_t);
- float sin_gamma_o = bsdf->extra->geom.w;
- float cos_gamma_o = cos_from_sin(sin_gamma_o);
- float gamma_o = safe_asinf(sin_gamma_o);
+ const float sin_gamma_o = bsdf->extra->geom.w;
+ const float cos_gamma_o = cos_from_sin(sin_gamma_o);
+ const float gamma_o = safe_asinf(sin_gamma_o);
- float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
- float cos_gamma_t = cos_from_sin(sin_gamma_t);
- float gamma_t = safe_asinf(sin_gamma_t);
+ const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
+ const float cos_gamma_t = cos_from_sin(sin_gamma_t);
+ const float gamma_t = safe_asinf(sin_gamma_t);
- Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
Spectrum Ap[4];
float Ap_energy[4];
hair_attenuation(
@@ -414,7 +404,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
}
u[1].x = max(u[1].x, 1e-5f);
- float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
+ const float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
float sin_theta_i = -fac * sin_theta_o +
cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
float cos_theta_i = cos_from_sin(sin_theta_i);
@@ -433,41 +423,37 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
else {
phi = M_2PI_F * u[0].y;
}
- float phi_i = phi_o + phi;
+ const float phi_i = phi_o + phi;
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- Spectrum F;
- float F_energy;
- float Mp, Np;
-
- /* Primary specular (R). */
- Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
- Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
- F = Ap[0] * Mp * Np;
- F_energy = Ap_energy[0] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Transmission (TT). */
- Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
- Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
- F += Ap[1] * Mp * Np;
- F_energy += Ap_energy[1] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
-
- /* Secondary specular (TRT). */
- Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
- F += Ap[2] * Mp * Np;
- F_energy += Ap_energy[2] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ Spectrum F = zero_spectrum();
+ float F_energy = 0.0f;
+
+ /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
+ for (int i = 0; i < 3; i++) {
+ const float Mp = longitudinal_scattering(angles[2 * i],
+ angles[2 * i + 1],
+ sin_theta_o,
+ cos_theta_o,
+ (i == 0) ? bsdf->m0_roughness :
+ (i == 1) ? 0.25f * bsdf->v :
+ 4.0f * bsdf->v);
+ const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
+ F += Ap[i] * Mp * Np;
+ F_energy += Ap_energy[i] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
/* Residual component (TRRT+). */
- Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
- Np = M_1_2PI_F;
- F += Ap[3] * Mp * Np;
- F_energy += Ap_energy[3] * Mp * Np;
- kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ {
+ const float Mp = longitudinal_scattering(
+ sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
+ const float Np = M_1_2PI_F;
+ F += Ap[3] * Mp * Np;
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
+ }
*eval = F;
*pdf = F_energy;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index f29897bc55d..4eb7cd5df22 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -357,146 +357,129 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro
bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNI > 0 && cosNO > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 33: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
-
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- /* use GTR1 for clearcoat */
- D = D_GTR1(cosThetaM, bsdf->alpha_x);
-
- /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
- alpha2 = 0.0625f;
- }
- else {
- /* use GTR2 otherwise */
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- }
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 33: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- /* eq. 34: now calculate G1(i,m) and G1(o,m) */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ /* use GTR1 for clearcoat */
+ D = D_GTR1(cosThetaM, bsdf->alpha_x);
+
+ /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
+ alpha2 = 0.0625f;
}
else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* use GTR2 otherwise */
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ }
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
- float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
- D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- /* G1(i,m) and G1(o,m) */
- float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
- float cosPhiO = dot(I, X);
- float sinPhiO = dot(I, Y);
+ D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
- float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
- (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
- alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
+ /* G1(i,m) and G1(o,m) */
+ float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
+ float cosPhiO = dot(I, X);
+ float sinPhiO = dot(I, Y);
- G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
+ float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
+ (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
+ alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
- float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
- float cosPhiI = dot(omega_in, X);
- float sinPhiI = dot(omega_in, Y);
+ G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
- float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
- (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
- alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
+ float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
+ float cosPhiI = dot(omega_in, X);
+ float sinPhiI = dot(omega_in, Y);
- G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
- }
+ float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
+ (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
+ alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
- float G = G1o * G1i;
+ G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
+ }
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
+ float G = G1o * G1i;
- Spectrum F = reflection_color(bsdf, omega_in, m);
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- F *= 0.25f * bsdf->extra->clearcoat;
- }
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
- Spectrum out = F * G * common;
+ Spectrum F = reflection_color(bsdf, omega_in, m);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ F *= 0.25f * bsdf->extra->clearcoat;
+ }
- /* eq. 2 in distribution of visible normals sampling
- * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
+ Spectrum out = F * G * common;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * `pdf = pm * 0.25 / dot(m, I);` */
- *pdf = G1o * common;
+ /* eq. 2 in distribution of visible normals sampling
+ * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
- return out;
- }
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * `pdf = pm * 0.25 / dot(m, I);` */
+ *pdf = G1o * common;
- return zero_spectrum();
+ return out;
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum(); /* vectors on same side -- not possible */
}
/* compute half-vector of the refraction (eq. 16) */
+ float m_eta = bsdf->ior;
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
@@ -533,6 +516,30 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderCl
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_ggx_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
@@ -811,111 +818,95 @@ ccl_device_inline float bsdf_beckmann_aniso_G1(
return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNO > 0 && cosNI > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNO > 0 && cosNI > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
-
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 25: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_G1(alpha_x, cosNO);
- G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- }
- else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 25: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_G1(alpha_x, cosNO);
+ G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
- /* G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
- G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
- }
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float G = G1o * G1i;
+ D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
- float out = G * common;
+ /* G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
+ G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
+ }
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+ float G = G1o * G1i;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * pdf = pm * 0.25 / dot(m, I); */
- *pdf = G1o * common;
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+ float out = G * common;
- return make_spectrum(out);
- }
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * pdf = pm * 0.25 / dot(m, I); */
+ *pdf = G1o * common;
- return zero_spectrum();
+ return make_spectrum(out);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum();
}
+
+ const float m_eta = bsdf->ior;
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
@@ -950,6 +941,30 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Sha
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_beckmann_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 34115749611..73cc0d292a1 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -415,21 +415,11 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
-ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
@@ -588,12 +578,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-ccl_device Spectrum
-bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
@@ -609,55 +598,22 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
- *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
- kernel_assert(*pdf >= 0.f);
- return mf_eval_glass(localI,
- localO,
- false,
- bsdf->extra->color,
- bsdf->alpha_x,
- bsdf->alpha_y,
- lcg_state,
- bsdf->ior,
- false,
- bsdf->extra->color);
-}
-
-ccl_device Spectrum
-bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
-{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
-
- if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
-
- float3 X, Y, Z;
- Z = bsdf->N;
- make_orthonormals(Z, &X, &Y);
-
- float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
- float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
+ const bool is_transmission = localO.z < 0.0f;
+ const bool use_fresnel = !is_transmission &&
+ (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
kernel_assert(*pdf >= 0.f);
return mf_eval_glass(localI,
localO,
- true,
+ !is_transmission,
bsdf->extra->color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
- bsdf->extra->cspec0);
+ (is_transmission) ? bsdf->extra->color : bsdf->extra->cspec0);
}
ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index b85390f0676..6912d5b3f18 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -47,10 +47,10 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
if (dot(bsdf->N, omega_in) > 0.0f) {
@@ -63,15 +63,6 @@ ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure
}
}
-ccl_device Spectrum bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index a50df0b397d..04bc165af30 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -44,10 +44,10 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_phong_ramp_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float m_exponent = bsdf->exponent;
@@ -70,15 +70,6 @@ ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure
return zero_spectrum();
}
-ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
-}
-
ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent)
{
return sqrt(1.0f / ((exponent + 2.0f) / 2.0f));
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
index 39cca1bd970..be8ee78fcac 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
@@ -109,18 +109,17 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
+ const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
+ const float3 V = I; // outgoing
+ const float3 L = omega_in; // incoming
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf);
}
@@ -130,15 +129,6 @@ ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const Shade
}
}
-ccl_device Spectrum bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
index fa46f47eb21..f6499cc437c 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
@@ -59,19 +59,19 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd,
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc;
-
- float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
+ const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
+ const float3 V = I; // outgoing
+ const float3 L = omega_in; // incoming
+ const float3 H = normalize(L + V);
+
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return calculate_principled_sheen_brdf(N, V, L, H, pdf);
}
@@ -81,15 +81,6 @@ ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderC
}
}
-ccl_device Spectrum bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 798bcfaf9e7..2f761974e9a 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -18,19 +18,10 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device Spectrum bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index 34836206ddf..e4f66245a0b 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -18,19 +18,10 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device Spectrum bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index c9086823de9..9f78c86b3b7 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -49,33 +49,29 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
return fminf(max_angle + smooth, M_PI_2_F);
}
-ccl_device Spectrum bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
- float max_angle = bsdf->size * M_PI_2_F;
- float smooth = bsdf->smooth * M_PI_2_F;
- float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f));
+ float cosNI = dot(bsdf->N, omega_in);
- float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ if (cosNI >= 0.0f) {
+ float max_angle = bsdf->size * M_PI_2_F;
+ float smooth = bsdf->smooth * M_PI_2_F;
+ float angle = safe_acosf(fmaxf(cosNI, 0.0f));
- if (eval > 0.0f) {
- float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
- *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return make_spectrum(*pdf * eval);
+ if (eval > 0.0f) {
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return make_spectrum(*pdf * eval);
+ }
}
- *pdf = 0.0f;
- return zero_spectrum();
-}
-ccl_device Spectrum bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
*pdf = 0.0f;
return zero_spectrum();
}
@@ -125,10 +121,10 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
@@ -153,15 +149,6 @@ ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosur
return zero_spectrum();
}
-ccl_device Spectrum bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index c2aee1e1633..9306e82b579 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -59,19 +59,10 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd,
}
}
-ccl_device Spectrum bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
-{
- *pdf = 0.0f;
- return zero_spectrum();
-}
-
-ccl_device Spectrum bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index a0ad7afe591..a39209bc937 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -807,7 +807,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
float3 wo = normalize_len(vertices[0].p - sd->P, &wo_len);
/* Initialize throughput and evaluate receiver bsdf * |n.wo|. */
- surface_shader_bsdf_eval(kg, sd, wo, false, throughput, ls->shader);
+ surface_shader_bsdf_eval(kg, sd, wo, throughput, ls->shader);
/* Update light sample with new position / direct.ion
* and keep pdf in vertex area measure */
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 7c31d673566..c766ea2a07e 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -171,7 +171,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
Ray ray ccl_optional_struct_init;
BsdfEval bsdf_eval ccl_optional_struct_init;
- const bool is_transmission = surface_shader_is_transmission(sd, ls.D);
+
+ const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
#ifdef __MNEE__
int mnee_vertex_count = 0;
@@ -182,13 +183,15 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
const bool use_caustics = kernel_data_fetch(lights, ls.lamp).use_caustics;
if (use_caustics) {
/* Are we on a caustic caster? */
- if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER))
+ if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER)) {
return;
+ }
/* Are we on a caustic receiver? */
- if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER))
+ if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER)) {
mnee_vertex_count = kernel_path_mnee_sample(
kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
+ }
}
}
}
@@ -207,8 +210,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
}
/* Evaluate BSDF. */
- const float bsdf_pdf = surface_shader_bsdf_eval(
- kg, sd, ls.D, is_transmission, &bsdf_eval, ls.shader);
+ const float bsdf_pdf = surface_shader_bsdf_eval(kg, sd, ls.D, &bsdf_eval, ls.shader);
bsdf_eval_mul(&bsdf_eval, light_eval / ls.pdf);
if (ls.shader & SHADER_USE_MIS) {
diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h
index 125aaae1b3f..7da81984a12 100644
--- a/intern/cycles/kernel/integrator/surface_shader.h
+++ b/intern/cycles/kernel/integrator/surface_shader.h
@@ -108,13 +108,6 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
}
/* BSDF */
-
-ccl_device_inline bool surface_shader_is_transmission(ccl_private const ShaderData *sd,
- const float3 omega_in)
-{
- return dot(sd->N, omega_in) < 0.0f;
-}
-
ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light_shader_flags)
{
if (!(light_shader_flags & SHADER_EXCLUDE_ANY)) {
@@ -141,7 +134,6 @@ ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light
ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
ccl_private ShaderData *sd,
const float3 omega_in,
- const bool is_transmission,
ccl_private const ShaderClosure *skip_sc,
ccl_private BsdfEval *result_eval,
float sum_pdf,
@@ -160,7 +152,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
float bsdf_pdf = 0.0f;
- Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf);
+ Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
if (bsdf_pdf != 0.0f) {
bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
@@ -184,14 +176,13 @@ ccl_device_inline
surface_shader_bsdf_eval(KernelGlobals kg,
ccl_private ShaderData *sd,
const float3 omega_in,
- const bool is_transmission,
ccl_private BsdfEval *bsdf_eval,
const uint light_shader_flags)
{
bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum());
return _surface_shader_bsdf_eval_mis(
- kg, sd, omega_in, is_transmission, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
+ kg, sd, omega_in, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
}
/* Randomly sample a BSSRDF or BSDF proportional to ShaderClosure.sample_weight. */
@@ -285,10 +276,9 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight);
if (sd->num_closure > 1) {
- const bool is_transmission = surface_shader_is_transmission(sd, *omega_in);
float sweight = sc->sample_weight;
*pdf = _surface_shader_bsdf_eval_mis(
- kg, sd, *omega_in, is_transmission, sc, bsdf_eval, *pdf * sweight, sweight, 0);
+ kg, sd, *omega_in, sc, bsdf_eval, *pdf * sweight, sweight, 0);
}
}