Use reflection BSDF for glossy reflections when roughness is 0.0 to

reduce computational expense and some code cleanup

Code cleanup includes:
- Code style cleanup and removed unused code
- Consolidated code in the bsdf_microfacet_multi_impl.h to reduce
  some computational expense
This commit is contained in:
2016-10-31 11:31:36 +01:00
parent a2dd0c5faf
commit 3dfc240e61
8 changed files with 122 additions and 145 deletions

View File

@@ -46,11 +46,9 @@ ccl_device float3 calculate_disney_diffuse_brdf(const DisneyDiffuseBsdf *bsdf,
float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * bsdf->roughness;
float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV); //lerp(1.0f, Fd90, FL) * lerp(1.0f, Fd90, FV);
float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
float value = M_1_PI_F * Fd;
value *= NdotL;
float value = M_1_PI_F * NdotL * Fd;
return make_float3(value, value, value);
}
@@ -72,8 +70,7 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, cons
float3 H = normalize(L + V);
if(dot(N, omega_in) > 0.0f) {
float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return calculate_disney_diffuse_brdf(bsdf, N, V, L, H, pdf);
}
else {
@@ -111,7 +108,7 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
#endif
}
else {
*pdf = 0;
*pdf = 0.0f;
}
return LABEL_REFLECT|LABEL_DIFFUSE;
}

View File

@@ -42,11 +42,7 @@ ccl_device float3 calculate_disney_sheen_brdf(const DisneySheenBsdf *bsdf,
float LdotH = dot(L, H);
float FH = schlick_fresnel(LdotH);
float value = FH;
value *= NdotL;
float value = schlick_fresnel(LdotH) * NdotL;
return make_float3(value, value, value);
}
@@ -68,8 +64,7 @@ ccl_device float3 bsdf_disney_sheen_eval_reflect(const ShaderClosure *sc, const
float3 H = normalize(L + V);
if(dot(N, omega_in) > 0.0f) {
float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
return calculate_disney_sheen_brdf(bsdf, N, V, L, H, pdf);
}
else {
@@ -107,7 +102,7 @@ ccl_device int bsdf_disney_sheen_sample(const ShaderClosure *sc,
#endif
}
else {
*pdf = 0;
*pdf = 0.0f;
}
return LABEL_REFLECT|LABEL_DIFFUSE;
}

View File

@@ -244,12 +244,10 @@ ccl_device_forceinline float3 microfacet_sample_stretched(
ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float3 L, float3 H) {
float3 F = make_float3(1.0f, 1.0f, 1.0f);
if(bsdf->extra) {
if(bsdf->extra->use_fresnel) {
float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
if(bsdf->extra && bsdf->extra->use_fresnel) {
float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
}
F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
}
return F;
@@ -528,7 +526,6 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
float common = D * (m_eta * m_eta) / (cosNO * Ht2);
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
@@ -579,11 +576,9 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
*eval = make_float3(1e6f, 1e6f, 1e6f);
/* if fresnel is used, calculate the color with reflection_color(...) */
if(bsdf->extra) {
if(bsdf->extra->use_fresnel) {
*pdf = 1.0f;
*eval = reflection_color(bsdf, *omega_in, m);
}
if(bsdf->extra && bsdf->extra->use_fresnel) {
*pdf = 1.0f;
*eval = reflection_color(bsdf, *omega_in, m);
}
}
else {
@@ -603,14 +598,12 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
float cosNI = dot(N, *omega_in);
/* eq. 34: now calculate G1(i,m) */
if(bsdf->extra) {
if(bsdf->extra->is_disney_clearcoat) {
/* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
alpha2 = 0.0625f;
if(bsdf->extra && bsdf->extra->is_disney_clearcoat) {
/* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
alpha2 = 0.0625f;
/* recalculate G1o */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
}
/* recalculate G1o */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
}
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
@@ -708,7 +701,6 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
/* see eval function for derivation */
float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2);
float out = G1i * fabsf(cosHI * cosHO) * common;
*pdf = cosHO * fabsf(cosHI) * common;

View File

@@ -29,7 +29,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
float3 wi,
float3 wo,
const bool wo_outside,
const float3 color,
const float3 color,
const float alpha_x,
const float alpha_y,
ccl_addr_space uint *lcg_state
@@ -38,7 +38,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
, bool use_fresnel
, const float3 cspec0
#elif defined(MF_MULTI_GLOSSY)
, float3 *n, float3 *k
, float3 *n, float3 *k
, const float eta
, bool use_fresnel
, const float3 cspec0
@@ -76,6 +76,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
/* Analytically compute single scattering for lower noise. */
float3 eval;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
#ifdef MF_MULTI_GLASS
eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
if(wo_outside)
@@ -83,14 +84,11 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
else
eval *= -lambda_r * beta(-lambda_r, shadowing_lambda+1.0f);
float3 eval_fresnel;
float3 t_color = cspec0;
float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
if(use_fresnel) {
throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wo), eta, F0, cspec0);
throughput = interpolate_fresnel_color(wi, normalize(wi + wo), eta, F0, cspec0);
eval_fresnel = throughput_fresnel * eval;
eval *= throughput;
}
#elif defined(MF_MULTI_DIFFUSE)
/* Diffuse has no special closed form for the single scattering bounce */
@@ -110,14 +108,11 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
eval = make_float3(val, val, val);
}
float3 eval_fresnel;
float3 t_color = cspec0;
float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
if(use_fresnel) {
throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wo), eta, F0, cspec0);
throughput = interpolate_fresnel_color(wi, wh, eta, F0, cspec0);
eval_fresnel = throughput_fresnel * val;
eval = throughput * val;
}
#endif
@@ -126,7 +121,6 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
float C1_r = 1.0f;
float G1_r = 0.0f;
bool outside = true;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
for(int order = 0; order < 10; order++) {
/* Sample microfacet height and normal */
@@ -151,7 +145,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
else
phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
eval_fresnel = throughput_fresnel * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
eval = throughput * phase * mf_G1(wo_outside ? wo : -wo, mf_C1((outside == wo_outside) ? hr : -hr), shadowing_lambda);
}
#endif
if(order > 0) {
@@ -162,16 +156,10 @@ ccl_device_forceinline 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)
eval_fresnel += throughput_fresnel * 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)
eval_fresnel += throughput_fresnel * 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);
}
@@ -188,49 +176,36 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(
}
if(use_fresnel && !next_outside) {
throughput_fresnel *= color;
throughput *= color;
}
else if(use_fresnel) {
t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
if(order > 0)
throughput_fresnel *= t_color;
else if(use_fresnel && order > 0) {
throughput *= interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
}
#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) {
t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
if(order > 0)
throughput_fresnel *= t_color;
}
else {
throughput_fresnel *= color;
if(use_fresnel && order > 0) {
throughput *= interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
}
wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
#endif
lambda_r = mf_lambda(wr, alpha);
#if defined(MF_MULTI_GLOSSY) || defined(MF_MULTI_GLASS)
if(!use_fresnel)
throughput *= color;
#else
throughput *= color;
#endif
C1_r = mf_C1(hr);
G1_r = mf_G1(wr, C1_r, lambda_r);
}
}
#if defined(MF_MULTI_GLASS) || defined(MF_MULTI_GLOSSY)
if(use_fresnel) {
if(swapped)
eval_fresnel *= fabsf(wi.z / wo.z);
return eval_fresnel;
}
#endif
if(swapped)
eval *= fabsf(wi.z / wo.z);
return eval;
@@ -263,18 +238,14 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3
float G1_r = 0.0f;
bool outside = true;
#ifdef MF_MULTI_GLASS
float3 t_color = cspec0;
float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
if(use_fresnel) {
throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
throughput = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
}
#elif defined(MF_MULTI_GLOSSY)
float3 t_color = cspec0;
float3 throughput_fresnel = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta);
if(use_fresnel) {
throughput_fresnel = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
throughput = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
}
#endif
@@ -284,10 +255,6 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3
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. */
*wo = outside? wr: -wr;
#if defined(MF_MULTI_GLASS) || defined(MF_MULTI_GLOSSY)
if(use_fresnel)
return throughput_fresnel;
#endif
return throughput;
}
/* Sample microfacet normal. */
@@ -295,8 +262,13 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3
lcg_step_float_addrspace(lcg_state)));
/* First-bounce color is already accounted for in mix weight. */
#if defined(MF_MULTI_GLASS) || defined(MF_MULTI_GLOSSY)
if(!use_fresnel && order > 0)
throughput *= color;
#else
if(order > 0)
throughput *= color;
#endif
/* Bounce from the microfacet. */
#ifdef MF_MULTI_GLASS
@@ -311,15 +283,15 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3
if(use_fresnel) {
if(!next_outside) {
throughput_fresnel *= color;
throughput *= color;
}
else {
t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
if(order == 0)
throughput_fresnel = t_color;
throughput = t_color;
else
throughput_fresnel *= t_color;
throughput *= t_color;
}
}
#elif defined(MF_MULTI_DIFFUSE)
@@ -328,12 +300,12 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3
lcg_step_float_addrspace(lcg_state));
#else /* MF_MULTI_GLOSSY */
if(use_fresnel) {
t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
if(order == 0)
throughput_fresnel = t_color;
throughput = t_color;
else
throughput_fresnel *= t_color;
throughput *= t_color;
}
wr = mf_sample_phase_glossy(-wr, n, k, &throughput, wm);
#endif

View File

@@ -131,11 +131,6 @@ ccl_device float schlick_fresnel(float u)
return m2 * m2 * m; // pow(m, 5)
}
ccl_device float sqr(float a)
{
return a * a;
}
ccl_device float smooth_step(float edge0, float edge1, float x)
{
float result;

View File

@@ -48,7 +48,7 @@ shader node_disney_bsdf(
vector T = Tangent;
float m_cdlum = 0.3 * BaseColor[0] + 0.6 * BaseColor[1] + 0.1 * BaseColor[2]; // luminance approx.
float m_cdlum = luminance(BaseColor);
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum : color(0.0, 0.0, 0.0); // normalize lum. to isolate hue+sat
/* rotate tangent */
@@ -63,9 +63,9 @@ shader node_disney_bsdf(
}
if (Sheen > 1e-5) {
color csheen0 = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
BSDF = BSDF + csheen0 * Sheen * disney_sheen(Normal);
BSDF = BSDF + sheen_color * Sheen * disney_sheen(Normal);
}
BSDF = BSDF * diffuse_weight;

View File

@@ -129,7 +129,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
// get the additional clearcoat normal and subsurface scattering radius
uint4 data_cn_ssr = read_node(kg, offset);
float3 CN = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : ccl_fetch(sd, N);
float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : ccl_fetch(sd, N);
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : make_float3(1.0f, 1.0f, 1.0f);
// get the subsurface color
@@ -147,23 +147,22 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
/* disable in case of diffuse ancestor, can't see it well then and
* adds considerably noise due to probabilities of continuing path
* getting lower and lower */
if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
subsurface = 0.0f;
}
if(subsurface < CLOSURE_WEIGHT_CUTOFF) {
/* diffuse */
if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) {
float3 diff_weight = weight * base_color * diffuse_weight;
/* diffuse */
if(subsurface < CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) {
float3 diff_weight = weight * base_color * diffuse_weight;
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
if(bsdf) {
bsdf->N = N;
bsdf->roughness = roughness;
if(bsdf) {
bsdf->N = N;
bsdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_disney_diffuse_setup(bsdf);
}
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_disney_diffuse_setup(bsdf);
}
}
else if(subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF) {
@@ -239,13 +238,13 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
/* sheen */
if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
float m_cdlum = linear_rgb_to_gray(base_color);
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
/* csheen0 */
float3 csheen0 = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint;
/* color of the sheen component */
float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint;
float3 sheen_weight = weight * sheen * csheen0 * diffuse_weight;
float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
DisneySheenBsdf *bsdf = (DisneySheenBsdf*)bsdf_alloc(sd, sizeof(DisneySheenBsdf), sheen_weight);
@@ -264,33 +263,60 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if(specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
float3 spec_weight = weight * specular_weight;
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
/* for roughness values close to 0 handle as a sharp reflection */
if(roughness <= 1e-2f) {
float spec_to_ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
if(bsdf && extra) {
bsdf->N = N;
bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
bsdf->T = T;
bsdf->extra = extra;
float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
float r2 = roughness * roughness;
bsdf->alpha_x = fmaxf(0.001f, r2 / aspect);
bsdf->alpha_y = fmaxf(0.001f, r2 * aspect);
float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
float m_cdlum = linear_rgb_to_gray(base_color);
float3 m_ctint = m_cdlum > 0.0f ? base_color / 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 - specular_tint) + m_ctint * specular_tint;
float3 cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
bsdf->extra->color = base_color;
float F0 = fresnel_dielectric_cos(1.0f, spec_to_ior);
float F0_norm = 1.0f / (1.0f - F0);
float FH = (fresnel_dielectric_cos(cosNO, spec_to_ior) - F0) * F0_norm;
/* setup bsdf */
if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf);
else /* use multi-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf);
/* Blend between white and a specular color with respect to the fresnel */
float3 refl_color = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight*refl_color);
if(bsdf) {
bsdf->N = N;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_reflection_setup(bsdf);
}
}
else {
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 = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
bsdf->T = T;
bsdf->extra = extra;
float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
float r2 = roughness * roughness;
bsdf->alpha_x = fmaxf(0.001f, r2 / aspect);
bsdf->alpha_y = fmaxf(0.001f, r2 * aspect);
float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
float3 m_ctint = m_cdlum > 0.0f ? base_color / 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 - specular_tint) + m_ctint * specular_tint;
bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
bsdf->extra->color = base_color;
/* setup bsdf */
if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf);
else /* use multi-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf);
}
}
}
#ifdef __CAUSTICS_TRICKS__
@@ -412,7 +438,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if(bsdf && extra) {
bsdf->N = CN;
bsdf->N = clearcoat_normal;
bsdf->ior = 1.5f;
bsdf->extra = extra;

View File

@@ -2553,9 +2553,9 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 resu
node_bsdf_diffuse(color, 0.0, N, result);
}
void node_bsdf_disney(vec4 base_color, vec4 subsurface_color, float metallic, float subsurface, float specular, float roughness,
float specular_tint, float anisotropic, float sheen, float sheen_tint, float clearcoat, float clearcoat_gloss, float ior,
float transparency, float refraction_roughness, float anisotropic_rotation, vec3 N, vec3 CN, vec3 T, out vec4 result)
void node_bsdf_disney(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
float clearcoat_gloss, float ior, float transparency, float refraction_roughness, vec3 N, vec3 CN, vec3 T, out vec4 result)
{
node_bsdf_diffuse(base_color, roughness, N, result);
}