forked from bartvdbraak/blender
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
This commit is contained in:
parent
bd249eb4f3
commit
6d19da0b2d
@ -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);
|
||||
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);
|
||||
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);
|
||||
eval = bsdf_phong_ramp_eval(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);
|
||||
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);
|
||||
eval = bsdf_translucent_eval(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_REFLECTION_ID:
|
||||
eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_reflection_eval(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_REFRACTION_ID:
|
||||
eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_refraction_eval(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_TRANSPARENT_ID:
|
||||
eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
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_reflect(sc, sd->I, omega_in, pdf);
|
||||
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_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
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_reflect(
|
||||
sc, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
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_reflect(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_microfacet_beckmann_eval(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);
|
||||
eval = bsdf_ashikhmin_shirley_eval(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);
|
||||
eval = bsdf_ashikhmin_velvet_eval(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);
|
||||
eval = bsdf_diffuse_toon_eval(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);
|
||||
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_reflect(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_hair_reflection_eval(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);
|
||||
eval = bsdf_hair_transmission_eval(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);
|
||||
eval = bsdf_principled_diffuse_eval(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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
@ -39,8 +39,7 @@ 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,
|
||||
ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -53,11 +52,11 @@ 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);
|
||||
@ -103,20 +102,10 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
|
||||
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,7 +135,11 @@ 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);
|
||||
@ -216,9 +209,8 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
|
||||
label = LABEL_REFLECT | LABEL_SINGULAR;
|
||||
}
|
||||
else {
|
||||
/* leave the rest to eval_reflect */
|
||||
*eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
|
||||
}
|
||||
/* leave the rest to eval */
|
||||
*eval = bsdf_ashikhmin_shirley_eval(sc, I, *omega_in, pdf);
|
||||
}
|
||||
|
||||
return label;
|
||||
|
@ -31,7 +31,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -42,7 +42,11 @@ 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) {
|
||||
if (!(cosNO > 0 && cosNI > 0)) {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
||||
float3 H = normalize(omega_in + I);
|
||||
|
||||
float cosNH = dot(N, H);
|
||||
@ -69,19 +73,6 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderC
|
||||
|
||||
*pdf = 0.5f * M_1_PI_F;
|
||||
return make_spectrum(out);
|
||||
}
|
||||
|
||||
*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();
|
||||
}
|
||||
|
||||
ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
|
||||
@ -101,7 +92,12 @@ 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) {
|
||||
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);
|
||||
@ -109,7 +105,12 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
|
||||
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) {
|
||||
if (!(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
|
||||
*pdf = 0.0f;
|
||||
*eval = zero_spectrum();
|
||||
return LABEL_NONE;
|
||||
}
|
||||
|
||||
float cosNHdivHO = cosNH / cosHO;
|
||||
cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
|
||||
|
||||
@ -126,16 +127,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
|
||||
float power = 0.25f * (D * G) / cosNO;
|
||||
|
||||
*eval = make_spectrum(power);
|
||||
}
|
||||
else {
|
||||
*pdf = 0.0f;
|
||||
*eval = zero_spectrum();
|
||||
}
|
||||
}
|
||||
else {
|
||||
*pdf = 0.0f;
|
||||
*eval = zero_spectrum();
|
||||
}
|
||||
|
||||
return LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_diffuse_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -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,16 +72,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
|
@ -47,7 +47,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -56,16 +56,14 @@ ccl_device Spectrum bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosu
|
||||
float3 N = bsdf->N;
|
||||
|
||||
float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
|
||||
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);
|
||||
}
|
||||
|
||||
ccl_device Spectrum bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
{
|
||||
}
|
||||
else {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
|
||||
|
@ -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,
|
||||
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,
|
||||
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;
|
||||
|
@ -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;
|
||||
Spectrum F = zero_spectrum();
|
||||
float F_energy = 0.0f;
|
||||
|
||||
/* 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;
|
||||
/* 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;
|
||||
{
|
||||
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;
|
||||
Spectrum F = zero_spectrum();
|
||||
float F_energy = 0.0f;
|
||||
|
||||
/* 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;
|
||||
/* 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;
|
||||
{
|
||||
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;
|
||||
|
@ -357,26 +357,21 @@ 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;
|
||||
@ -467,36 +462,24 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClo
|
||||
*pdf = G1o * common;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
||||
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,26 +818,21 @@ 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);
|
||||
|
||||
@ -887,35 +889,24 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shad
|
||||
*pdf = G1o * common;
|
||||
|
||||
return make_spectrum(out);
|
||||
}
|
||||
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -415,17 +415,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf,
|
||||
@ -588,8 +578,7 @@ 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,
|
||||
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,
|
||||
@ -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,
|
||||
|
@ -47,7 +47,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -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,
|
||||
|
@ -44,7 +44,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_phong_ramp_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -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));
|
||||
|
@ -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,
|
||||
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,
|
||||
|
@ -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,
|
||||
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,
|
||||
|
@ -18,16 +18,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
|
@ -18,16 +18,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
|
@ -49,15 +49,18 @@ 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,
|
||||
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 cosNI = dot(bsdf->N, omega_in);
|
||||
|
||||
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(dot(bsdf->N, omega_in), 0.0f));
|
||||
float angle = safe_acosf(fmaxf(cosNI, 0.0f));
|
||||
|
||||
float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
|
||||
|
||||
@ -67,15 +70,8 @@ ccl_device Spectrum bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosu
|
||||
*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,7 +121,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
@ -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,
|
||||
|
@ -59,16 +59,7 @@ 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,
|
||||
ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
|
@ -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 */
|
||||
|
@ -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,16 +183,18 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mnee_vertex_count > 0) {
|
||||
/* Create shadow ray after successful manifold walk:
|
||||
* emission_sd contains the last interface intersection and
|
||||
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user