Implemented the fresnel in the multi-scatter GGX for the Disney BSDF

- The specular/metallic part uses the multi-scatter GGX
- The fresnel of the metallic part is controlled by the specular value
- The color of the reflection part when using transparency can be
  controlled by the specularTint value
This commit is contained in:
2016-08-16 15:17:12 +02:00
parent 88567af085
commit ef29aaee1a
6 changed files with 245 additions and 34 deletions

View File

@@ -95,6 +95,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
label = bsdf_microfacet_ggx_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
label = bsdf_microfacet_multi_ggx_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf, &ccl_fetch(sd, lcg_state));
@@ -295,6 +296,7 @@ float3 bsdf_eval(KernelGlobals *kg,
eval = bsdf_microfacet_ggx_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_REFRACTION_ID:
eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf, &ccl_fetch(sd, lcg_state));
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:

View File

@@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct MicrofacetExtra {
float3 color, cspec0;
bool use_fresnel, is_disney_clearcoat;
bool use_fresnel, is_disney_clearcoat, initial_outside, only_refractions, only_reflections;
} MicrofacetExtra;
typedef ccl_addr_space struct MicrofacetBsdf {
@@ -410,7 +410,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
float3 F = make_float3(1.0f, 1.0f, 1.0f);
if (bsdf->extra) {
if (bsdf->extra->use_fresnel) {
float FH = schlick_fresnel(dot(omega_in, m));
float FH = fresnel_dielectric_cos(dot(omega_in, m), bsdf->ior);
F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH);
}
@@ -485,7 +485,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
float3 F = make_float3(1.0f, 1.0f, 1.0f);
if (bsdf->extra) {
if (bsdf->extra->use_fresnel) {
float FH = schlick_fresnel(dot(omega_in, Ht));
float FH = fresnel_dielectric_cos(dot(omega_in, Ht), bsdf->ior);
F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH);
}
@@ -599,7 +599,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
float3 F = make_float3(1.0f, 1.0f, 1.0f);
if (bsdf->extra) {
if (bsdf->extra->use_fresnel) {
float FH = schlick_fresnel(dot(*omega_in, m));
float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior);
F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH);
}
@@ -670,7 +670,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
float3 F = make_float3(1.0f, 1.0f, 1.0f);
if (bsdf->extra) {
if (bsdf->extra->use_fresnel) {
float FH = schlick_fresnel(dot(*omega_in, m));
float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior);
F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH);
}

View File

@@ -370,6 +370,13 @@ ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf, bool use_fr
return bsdf_microfacet_multi_ggx_common_setup(bsdf, use_fresnel);
}
ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false)
{
bsdf->alpha_y = bsdf->alpha_x;
return bsdf_microfacet_multi_ggx_common_setup(bsdf, use_fresnel);
}
ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
*pdf = 0.0f;
return make_float3(0.0f, 0.0f, 0.0f);
@@ -392,7 +399,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
return mf_eval_glossy(localI, localO, true, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, NULL, NULL);
return mf_eval_glossy(localI, localO, true, bsdf->extra->color, bsdf->extra->cspec0, bsdf->alpha_x, bsdf->alpha_y, lcg_state, NULL, NULL, bsdf->ior, bsdf->extra->use_fresnel);
}
ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state)
@@ -409,7 +416,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderC
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO;
*eval = mf_sample_glossy(localI, &localO, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, NULL, NULL);
*eval = mf_sample_glossy(localI, &localO, bsdf->extra->color, bsdf->extra->cspec0, bsdf->alpha_x, bsdf->alpha_y, lcg_state, NULL, NULL, bsdf->ior, bsdf->extra->use_fresnel);
if(is_aniso)
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
@@ -426,7 +433,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderC
/* Multiscattering GGX Glass closure */
ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false)
ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false, bool initial_outside = true, bool only_refractions = false, bool only_reflections = false)
{
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
@@ -438,6 +445,9 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf, bool
bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
bsdf->extra->initial_outside = initial_outside;
bsdf->extra->only_refractions = only_refractions;
bsdf->extra->only_reflections = only_reflections;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
@@ -446,6 +456,10 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf, bool
ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
if (bsdf->extra->only_reflections)
return make_float3(0.0f, 0.0f, 0.0f);
float3 X, Y, Z;
Z = bsdf->N;
make_orthonormals(Z, &X, &Y);
@@ -454,11 +468,15 @@ ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClos
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);
return mf_eval_glass(localI, localO, false, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior);
return mf_eval_glass(localI, localO, false, bsdf->extra->color, bsdf->extra->cspec0, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior);
}
ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) {
const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
if (bsdf->extra->only_refractions)
return make_float3(0.0f, 0.0f, 0.0f);
float3 X, Y, Z;
Z = bsdf->N;
make_orthonormals(Z, &X, &Y);
@@ -467,7 +485,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosu
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);
return mf_eval_glass(localI, localO, true, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior);
return mf_eval_glass(localI, localO, true, bsdf->extra->color, bsdf->extra->cspec0, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, bsdf->extra->use_fresnel, bsdf->extra->initial_outside);
}
ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state)
@@ -480,7 +498,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const S
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO;
*eval = mf_sample_glass(localI, &localO, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior);
*eval = mf_sample_glass(localI, &localO, bsdf->extra->color, bsdf->extra->cspec0, bsdf->alpha_x, bsdf->alpha_y, lcg_state, bsdf->ior, bsdf->extra->use_fresnel, bsdf->extra->initial_outside, bsdf->extra->only_refractions, bsdf->extra->only_reflections);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
*eval *= *pdf;

View File

@@ -29,14 +29,19 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
float3 wi,
float3 wo,
const bool wo_outside,
const float3 color,
const float3 color,
const float3 cspec0,
const float alpha_x,
const float alpha_y,
ccl_addr_space uint *lcg_state
#ifdef MF_MULTI_GLASS
, const float eta
, bool use_fresnel = false
, bool initial_outside = true
#elif defined(MF_MULTI_GLOSSY)
, float3 *n, float3 *k
, float3 *n, float3 *k
, const float eta = 1.0f
, bool use_fresnel = false
#endif
)
{
@@ -77,6 +82,18 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
eval *= -lambda_r / (shadowing_lambda - lambda_r);
else
eval *= -lambda_r * beta(-lambda_r, shadowing_lambda+1.0f);
float3 eval2;
float3 t_color = cspec0;
float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
float F0_norm = 1.0f / (1.0f - F0);
if (use_fresnel && initial_outside) {
float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wo)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wo))); //
throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
eval2 = throughput2 * eval;
}
#elif defined(MF_MULTI_DIFFUSE)
/* Diffuse has no special closed form for the single scattering bounce */
eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -94,6 +111,18 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
else {
eval = make_float3(val, val, val);
}
float3 eval2;
float3 t_color = cspec0;
float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
float F0_norm = 1.0f / (1.0f - F0);
if (use_fresnel) {
float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wo)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wo))); //
throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
eval2 = throughput2 * val;
}
#endif
float3 wr = -wi;
@@ -116,6 +145,18 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
const float G2_G1 = -lambda_r / (shadowing_lambda - lambda_r);
eval += throughput * G2_G1 * mf_eval_phase_diffuse(wo, wm);
}
#endif
#ifdef MF_MULTI_GLASS
if (order == 0 && use_fresnel) {
/* Evaluate amount of scattering towards wo on this microfacet. */
float3 phase;
if (outside)
phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
else
phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
eval2 = throughput2 * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
}
#endif
if(order > 0) {
/* Evaluate amount of scattering towards wo on this microfacet. */
@@ -125,10 +166,16 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
else
phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f/eta);
if (use_fresnel && initial_outside)
eval2 += throughput2 * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
#elif defined(MF_MULTI_DIFFUSE)
phase = mf_eval_phase_diffuse(wo, wm);
#else /* MF_MULTI_GLOSSY */
phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha, n, k) * throughput;
if (use_fresnel)
eval2 += throughput2 * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
#endif
eval += throughput * phase * mf_G1(wo_outside? wo: -wo, mf_C1((outside == wo_outside)? hr: -hr), shadowing_lambda);
}
@@ -136,17 +183,39 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
/* Bounce from the microfacet. */
#ifdef MF_MULTI_GLASS
bool next_outside;
float3 wi_prev = -wr;
wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, lcg_step_float_addrspace(lcg_state), &next_outside);
if(!next_outside) {
outside = !outside;
wr = -wr;
hr = -hr;
}
if (use_fresnel && initial_outside && outside && next_outside) {
float FH = (fresnel_dielectric_cos(dot(wi_prev, wm), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi_prev, wm)); //
t_color = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
if (order > 0)
throughput2 *= t_color;
}
else {
throughput2 *= color;
}
#elif defined(MF_MULTI_DIFFUSE)
wr = mf_sample_phase_diffuse(wm,
lcg_step_float_addrspace(lcg_state),
lcg_step_float_addrspace(lcg_state));
#else /* MF_MULTI_GLOSSY */
if (use_fresnel) {
float FH = (fresnel_dielectric_cos(dot(-wr, wm), eta) - F0) * F0_norm; //schlick_fresnel(dot(-wr, wm)); //
t_color = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
if (order > 0)
throughput2 *= t_color;
}
else {
throughput2 *= color;
}
wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
#endif
@@ -159,6 +228,15 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
}
}
#if defined(MF_MULTI_GLASS) || defined(MF_MULTI_GLOSSY)
if (use_fresnel) {
if (swapped)
eval2 *= fabsf(wi.z / wo.z);
return eval2;
}
#endif
if(swapped)
eval *= fabsf(wi.z / wo.z);
return eval;
@@ -168,11 +246,17 @@ ccl_device_inline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
* escaped the surface in wo. The function returns the throughput between wi and wo.
* Without reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal.
*/
ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const float3 color, const float alpha_x, const float alpha_y, ccl_addr_space uint *lcg_state
ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const float3 color, const float3 cspec0, const float alpha_x, const float alpha_y, ccl_addr_space uint *lcg_state
#ifdef MF_MULTI_GLASS
, const float eta
, bool use_fresnel = false
, bool initial_outside = true
, bool only_refractions = false
, bool only_reflections = false
#elif defined(MF_MULTI_GLOSSY)
, float3 *n, float3 *k
, const float eta = 1.0f
, bool use_fresnel = false
#endif
)
{
@@ -185,13 +269,42 @@ ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const
float C1_r = 1.0f;
float G1_r = 0.0f;
bool outside = true;
#ifdef MF_MULTI_GLASS
float3 t_color = cspec0;
float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
float F0_norm = 1.0f / (1.0f - F0);
if (use_fresnel && initial_outside) {
float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wr)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wr))); //
throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
#else defined(MF_MULTI_GLOSSY)
float3 t_color = cspec0;
float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
float F0_norm = 1.0f / (1.0f - F0);
if (use_fresnel) {
float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wr)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wr))); //
throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
#endif
int order;
for(order = 0; order < 10; order++) {
/* Sample microfacet height. */
if(!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, lcg_step_float_addrspace(lcg_state))) {
/* The random walk has left the surface. */
#ifdef MF_MULTI_GLASS
if ((only_refractions && outside && initial_outside) || (only_reflections && !outside)) {
*wo = make_float3(0.0f, 0.0f, 1.0f);
return make_float3(0.0f, 0.0f, 0.0f);
}
#endif
*wo = outside? wr: -wr;
#if defined(MF_MULTI_GLASS) || defined(MF_MULTI_GLOSSY)
if (use_fresnel)
return throughput2;
#endif
return throughput;
}
/* Sample microfacet normal. */
@@ -205,17 +318,42 @@ ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const
/* Bounce from the microfacet. */
#ifdef MF_MULTI_GLASS
bool next_outside;
float3 wi_prev = -wr;
wr = mf_sample_phase_glass(-wr, outside? eta: 1.0f/eta, wm, lcg_step_float_addrspace(lcg_state), &next_outside);
if(!next_outside) {
hr = -hr;
wr = -wr;
outside = !outside;
}
if (use_fresnel) {
if (initial_outside && outside && next_outside) {
float FH = (fresnel_dielectric_cos(dot(wi_prev, wm), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi_prev, wm)); //
t_color = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
if (order == 0)
throughput2 = t_color;
else
throughput2 *= t_color;
}
else {
throughput2 *= color;
}
}
#elif defined(MF_MULTI_DIFFUSE)
wr = mf_sample_phase_diffuse(wm,
lcg_step_float_addrspace(lcg_state),
lcg_step_float_addrspace(lcg_state));
#else /* MF_MULTI_GLOSSY */
if (use_fresnel) {
float FH = (fresnel_dielectric_cos(dot(-wr, wm), eta) - F0) * F0_norm; //schlick_fresnel(dot(-wr, wm)); //
t_color = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
if (order == 0)
throughput2 = t_color;
else
throughput2 *= t_color;
}
wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
#endif

View File

@@ -100,6 +100,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float clearcoatGloss = stack_load_float(stack, clearcoatGloss_offset);
float transparency = stack_load_float(stack, transparency_offset);
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
float refraction_roughness = 1.0f; // TODO: add parameter for this!
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
/* rotate tangent */
@@ -236,14 +237,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif
if (specular != 0.0f || metallic != 0.0f) {
float3 spec_weight = weight * specular_weight;
float3 spec_weight = weight * specular_weight/* * (specular * (1.0f - metallic) + metallic)*/;
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf && extra) {
bsdf->N = N;
bsdf->ior = 0.0f;
bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
bsdf->T = T;
bsdf->extra = extra;
@@ -257,15 +258,16 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float3 m_ctint = m_cdlum > 0.0f ? baseColor / m_cdlum : make_float3(0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat
float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint) + m_ctint * specularTint;
bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + baseColor * metallic;
bsdf->extra->cspec0 = (/*fresnel_dielectric_cos(1.0f, ior)*/specular * 0.08f * tmp_col) * (1.0f - metallic) + baseColor * metallic;
bsdf->extra->color = baseColor;
/* setup bsdf */
#ifdef __DISNEY_SPECULAR_MULTI_GGX__
//#define __DISNEY_SPECULAR_MULTI_GGX__
//#ifdef __DISNEY_SPECULAR_MULTI_GGX__
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf, true);
#else
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true);
#endif
//#else
// ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true);
//#endif
}
}
#ifdef __CAUSTICS_TRICKS__
@@ -277,24 +279,74 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if (kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif
if (specular_weight < 1.0f) {
float3 glass_weight = baseColor * weight * (1.0f - specular_weight);
float3 glass_weight = /*baseColor */ weight * (1.0f - specular_weight);
float3 cspec0 = baseColor * specularTint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint);
bool frontfacing = (ccl_fetch(sd, flag) & SD_BACKFACING) == 0;
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (refraction_roughness == 0.0f) {
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness * roughness;
bsdf->alpha_y = roughness * roughness;
bsdf->ior = ior;
bsdf->alpha_x = roughness * roughness;
bsdf->alpha_y = roughness * roughness;
bsdf->ior = ior;
bsdf->extra->color = baseColor;
bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing);
}
}
else {
{
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness * roughness;
bsdf->alpha_y = roughness * roughness;
bsdf->ior = ior;
bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing, false, true);
}
}
{
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight * (1.0f - fresnel));
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
refraction_roughness = 1.0f - (1.0f - roughness) * (1.0f - refraction_roughness);
bsdf->alpha_x = refraction_roughness * refraction_roughness;
bsdf->alpha_y = refraction_roughness * refraction_roughness;
bsdf->ior = ior;
bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing, true);
}
}
}
}
#ifdef __CAUSTICS_TRICKS__

View File

@@ -417,6 +417,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID,
CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID,