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:
@@ -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:
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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__
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user