Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPascal Schoen <pascal_schoen@gmx.net>2016-09-16 09:47:56 +0300
committerPascal Schoen <pascal_schoen@gmx.net>2016-09-16 09:47:56 +0300
commit3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd (patch)
tree68d84cded51b493ec2681761811f34fd9b74646d /intern/cycles
parent7cb37d711938e5626651db21f20da50edd96abaf (diff)
Fixed a bug in the Disney BSDF that caused specular reflections to be too
bright and diffuse is now reacting to the roughness again - A normalization for the fresnel was missing which caused the specular reflections to become too bright for the single-scatter GGX - The roughness value for the diffuse BSSRDF part has always been overwritten and thus always 0 - Also the performance for refractive materials with roughness=0.0 has been improved
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/kernel/closure/bsdf_disney_specular.h68
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h56
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h16
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h15
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp68
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h2
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h64
7 files changed, 175 insertions, 114 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h
index 7e8139fd040..b83bb2920fa 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_specular.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h
@@ -35,34 +35,39 @@
CCL_NAMESPACE_BEGIN
+typedef ccl_addr_space struct DisneySpecularExtra {
+ float3 T, baseColor, cspec0;
+ bool alpha_x, alpha_y, rough_g, ior;
+} DisneySpecularExtra;
+
typedef ccl_addr_space struct DisneySpecularBsdf {
SHADER_CLOSURE_BASE;
- float specular, specularTint, roughness, metallic, anisotropic, alpha_x, alpha_y, rough_g;
- float3 N, T;
- float3 baseColor, cspec0;
+ float specular, specularTint, roughness, metallic, anisotropic;
+ float3 N;
+ DisneySpecularExtra *extra;
} DisneySpecularBsdf;
ccl_device int bsdf_disney_specular_setup(DisneySpecularBsdf *bsdf)
{
- float m_cdlum = 0.3f * bsdf->baseColor.x + 0.6f * bsdf->baseColor.y + 0.1f * bsdf->baseColor.z; // luminance approx.
+ float m_cdlum = 0.3f * bsdf->extra->baseColor.x + 0.6f * bsdf->extra->baseColor.y + 0.1f * bsdf->extra->baseColor.z; // luminance approx.
- float3 m_ctint = m_cdlum > 0.0f ? bsdf->baseColor / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
+ float3 m_ctint = m_cdlum > 0.0f ? bsdf->extra->baseColor / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - bsdf->specularTint) + m_ctint * bsdf->specularTint; // lerp(make_float3(1.0f, 1.0f, 1.0f), m_ctint, sc->data2/*specularTint*/);
- bsdf->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - bsdf->metallic) + bsdf->baseColor * bsdf->metallic; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/);
+ bsdf->extra->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - bsdf->metallic) + bsdf->extra->baseColor * bsdf->metallic; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/);
float aspect = safe_sqrtf(1.0f - bsdf->anisotropic * 0.9f);
float r2 = sqr(bsdf->roughness);
/* ax */
- bsdf->alpha_x = fmaxf(0.001f, r2 / aspect);
+ bsdf->extra->alpha_x = fmaxf(0.001f, r2 / aspect);
/* ay */
- bsdf->alpha_y = fmaxf(0.001f, r2 * aspect);
+ bsdf->extra->alpha_y = fmaxf(0.001f, r2 * aspect);
/* rough_g */
- bsdf->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f);
+ bsdf->extra->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f);
bsdf->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID;
return SD_BSDF|SD_BSDF_HAS_EVAL;
@@ -75,7 +80,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
float3 N = bsdf->N;
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f)
+ if (bsdf->extra->alpha_x*bsdf->extra->alpha_y <= 1e-7f)
return make_float3(0.0f, 0.0f, 0.0f);
float cosNO = dot(N, I);
@@ -84,10 +89,10 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
if (cosNI > 0 && cosNO > 0) {
/* get half vector */
float3 m = normalize(omega_in + I);
- float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
+ float alpha2 = bsdf->extra->alpha_x * bsdf->extra->alpha_y;
float D, G1o, G1i;
- if (bsdf->alpha_x == bsdf->alpha_y) {
+ if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) {
/* isotropic
* eq. 20: (F*G*D)/(4*in*on)
* eq. 33: first we calculate D(m) */
@@ -104,12 +109,12 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
else {
/* anisotropic */
float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y);
// distribution
float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x/(local_m.z*bsdf->alpha_x);
- float slope_y = -local_m.y/(local_m.z*bsdf->alpha_y);
+ float slope_x = -local_m.x/(local_m.z*bsdf->extra->alpha_x);
+ float slope_y = -local_m.y/(local_m.z*bsdf->extra->alpha_y);
float slope_len = 1 + slope_x*slope_x + slope_y*slope_y;
float cosThetaM = local_m.z;
@@ -123,7 +128,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
float cosPhiO = dot(I, X);
float sinPhiO = dot(I, Y);
- float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiO*sinPhiO)*(bsdf->alpha_y*bsdf->alpha_y);
+ float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiO*sinPhiO)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO;
G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
@@ -132,7 +137,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
float cosPhiI = dot(omega_in, X);
float sinPhiI = dot(omega_in, Y);
- float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y);
+ float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
@@ -144,7 +149,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con
float common = D * 0.25f / cosNO;
float FH = schlick_fresnel(dot(omega_in, m));
- float3 F = bsdf->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);
+ float3 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);
float3 out = F * G * common;
@@ -181,25 +186,23 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
if(cosNO > 0) {
float3 X, Y, Z = N;
- if (bsdf->alpha_x == bsdf->alpha_y)
+ if (bsdf->extra->alpha_x == bsdf->extra->alpha_y)
make_orthonormals(Z, &X, &Y);
else
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y);
/* importance sampling with distribution of visible normals. vectors are
* transformed to local space before and after */
float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
float3 local_m;
- float3 m;
float G1o;
- local_m = importance_sample_microfacet_stretched(local_I, bsdf->alpha_x, bsdf->alpha_y,
+ local_m = importance_sample_microfacet_stretched(local_I, bsdf->extra->alpha_x, bsdf->extra->alpha_y,
randu, randv, false, &G1o);
- m = X*local_m.x + Y*local_m.y + Z*local_m.z;
+ float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z;
float cosThetaM = local_m.z;
- /* reflection or refraction? */
float cosMO = dot(m, I);
if(cosMO > 0) {
@@ -207,7 +210,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
*omega_in = 2 * cosMO * m - I;
if(dot(Ng, *omega_in) > 0) {
- if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+ if (bsdf->extra->alpha_x*bsdf->extra->alpha_y <= 1e-7f) {
/* some high number for MIS */
*pdf = 1e6f;
*eval = make_float3(1e6f, 1e6f, 1e6f);
@@ -215,10 +218,10 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
else {
/* microfacet normal is visible to this ray */
/* eq. 33 */
- float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
+ float alpha2 = bsdf->extra->alpha_x * bsdf->extra->alpha_y;
float D, G1i;
- if (bsdf->alpha_x == bsdf->alpha_y) {
+ if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) {
float cosThetaM2 = cosThetaM * cosThetaM;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
float tanThetaM2 = 1/(cosThetaM2) - 1;
@@ -232,8 +235,8 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
}
else {
/* anisotropic distribution */
- float slope_x = -local_m.x / (local_m.z*bsdf->alpha_x);
- float slope_y = -local_m.y / (local_m.z*bsdf->alpha_y);
+ float slope_x = -local_m.x / (local_m.z*bsdf->extra->alpha_x);
+ float slope_y = -local_m.y / (local_m.z*bsdf->extra->alpha_y);
float slope_len = 1 + slope_x*slope_x + slope_y*slope_y;
float cosThetaM = local_m.z;
@@ -249,7 +252,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
float cosPhiI = dot(*omega_in, X);
float sinPhiI = dot(*omega_in, Y);
- float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y);
+ float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y);
alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI;
G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
@@ -259,8 +262,9 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc,
float common = (G1o * D) * 0.25f / cosNO;
*pdf = common;
- float FH = schlick_fresnel(dot(*omega_in, m));
- float3 F = bsdf->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);
+ float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->extra->ior);
+ //float FH = schlick_fresnel(dot(*omega_in, m));
+ float3 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);
*eval = G1i * common * F;
}
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 9ab9b17efe5..6c2f2958af9 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -410,9 +410,17 @@ 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 = 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);
+ /* Calculate the fresnel interpolation factor
+ * The value from fresnel_dielectric_cos(...) has to be normalized because
+ * the cspec0 keeps the F0 color
+ */
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(omega_in, m), bsdf->ior) - F0) * F0_norm;
+ //float FH = schlick_fresnel(dot(omega_in, m));
+
+ /* Blend between white and a specular color with respect to the fresnel */
+ F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
}
@@ -485,9 +493,17 @@ 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 = 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);
+ /* Calculate the fresnel interpolation factor
+ * The value from fresnel_dielectric_cos(...) has to be normalized because
+ * the cspec0 keeps the F0 color
+ */
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(omega_in, Ht), bsdf->ior) - F0) * F0_norm;
+ //float FH = schlick_fresnel(dot(omega_in, Ht));
+
+ /* Blend between white and a specular color with respect to the fresnel */
+ F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
}
@@ -599,9 +615,17 @@ 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 = 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);
+ /* Calculate the fresnel interpolation factor
+ * The value from fresnel_dielectric_cos(...) has to be normalized because
+ * the cspec0 keeps the F0 color
+ */
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior) - F0) * F0_norm;
+ //float FH = schlick_fresnel(dot(*omega_in, m));
+
+ /* Blend between white and a specular color with respect to the fresnel */
+ F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
}
@@ -670,9 +694,17 @@ 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 = 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);
+ /* Calculate the fresnel interpolation factor
+ * The value from fresnel_dielectric_cos(...) has to be normalized because
+ * the cspec0 keeps the F0 color
+ */
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior) - F0) * F0_norm;
+ //float FH = schlick_fresnel(dot(*omega_in, m));
+
+ /* Blend between white and a specular color with respect to the fresnel */
+ F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 1d21614ecee..45fdecfd554 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -37,8 +37,11 @@ CCL_NAMESPACE_BEGIN
/* REFLECTION */
-ccl_device int bsdf_reflection_setup(MicrofacetBsdf *bsdf)
+ccl_device int bsdf_reflection_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false)
{
+ if (bsdf->extra) {
+ bsdf->extra->use_fresnel = use_fresnel;
+ }
bsdf->type = CLOSURE_BSDF_REFLECTION_ID;
return SD_BSDF;
}
@@ -70,6 +73,17 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_float3(1e6f, 1e6f, 1e6f);
+
+ if (bsdf->extra) {
+ if (bsdf->extra->use_fresnel) {
+ *pdf = 1.0f;
+
+ float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
+ float F0_norm = 1.0f / (1.0f - F0);
+ float FH = (fresnel_dielectric_cos(dot(I, normalize(I + *omega_in)), bsdf->ior) - F0) * F0_norm;
+ *eval = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
+ }
+ }
}
}
return LABEL_REFLECT|LABEL_SINGULAR;
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index b713ff56b2f..ce28f0dbcbe 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -364,10 +364,19 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type)
/* revert to diffuse BSDF if radius too small */
int flag;
if (type == CLOSURE_BSSRDF_DISNEY_ID) {
+ float roughness = bssrdf->roughness;
+ float3 baseColor = bssrdf->baseColor;
+ float3 N = bssrdf->N;
+ float3 weight = bssrdf->weight;
+ float sample_weight = bssrdf->sample_weight;
+
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bssrdf;
- bsdf->N = bssrdf->N;
- bsdf->roughness = bssrdf->roughness;
- bsdf->baseColor = bssrdf->baseColor;
+
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+ bsdf->baseColor = baseColor;
+ bsdf->weight = weight;
+ bsdf->sample_weight = sample_weight;
flag = bsdf_disney_diffuse_setup(bsdf);
bsdf->type = CLOSURE_BSDF_BSSRDF_DISNEY_ID;
}
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 9711f914ef2..4418da3223c 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -192,16 +192,16 @@ BSDF_CLOSURE_CLASS_BEGIN(DisneySheen, disney_sheen, DisneySheenBsdf, LABEL_DIFFU
CLOSURE_FLOAT_PARAM(DisneySheenClosure, params.sheenTint),
BSDF_CLOSURE_CLASS_END(DisneySheen, disney_sheen)
-BSDF_CLOSURE_CLASS_BEGIN(DisneySpecular, disney_specular, DisneySpecularBsdf, LABEL_GLOSSY | LABEL_REFLECT)
+/*BSDF_CLOSURE_CLASS_BEGIN(DisneySpecular, disney_specular, DisneySpecularBsdf, LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.N),
CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.T),
- CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.baseColor),
+ CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->baseColor),
CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.metallic),
CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specular),
CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specularTint),
CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.roughness),
CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.anisotropic),
-BSDF_CLOSURE_CLASS_END(DisneySpecular, disney_specular)
+BSDF_CLOSURE_CLASS_END(DisneySpecular, disney_specular)*/
BSDF_CLOSURE_CLASS_BEGIN(DisneyClearcoat, disney_clearcoat, DisneyClearcoatBsdf, LABEL_GLOSSY|LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(DisneyClearcoatClosure, params.N),
@@ -363,59 +363,49 @@ CCLOSURE_PREPARE(bsdf_disney_sheen_prepare, DisneySheenClosure)
*/
/* DISNEY SPECULAR */
-/*class DisneySpecularClosure : public CBSDFClosure {
+class DisneySpecularClosure : public CBSDFClosure {
public:
- DisneySpecularClosure() : CBSDFClosure(LABEL_REFLECT | LABEL_GLOSSY)
- {}
-
- void setup()
- {
- sc.prim = this;
- m_shaderdata_flag = bsdf_disney_specular_setup(&sc);
- }
-
- void blur(float roughness)
- {
- }
+ DisneySpecularBsdf params;
- float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ DisneySpecularBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
{
- return bsdf_disney_specular_eval_reflect(&sc, omega_out, omega_in, &pdf);
- }
+ if (!skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
+ DisneySpecularBsdf *bsdf = (DisneySpecularBsdf*)bsdf_alloc_osl(sd, sizeof(DisneySpecularBsdf), weight, &params);
+ DisneySpecularExtra *extra = (DisneySpecularExtra*)closure_alloc_extra(sd, sizeof(DisneySpecularExtra));
+ if (bsdf && extra) {
+ bsdf->extra = extra;
+ return bsdf;
+ }
+ }
- float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
- {
- return bsdf_disney_specular_eval_transmit(&sc, omega_out, omega_in, &pdf);
+ return NULL;
}
- int sample(const float3 &Ng, const float3 &omega_out, const float3 &domega_out_dx,
- const float3 &domega_out_dy, float randu, float randv, float3 &omega_in,
- float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const
+ void setup(ShaderData *sd, int path_flag, float3 weight)
{
- return bsdf_disney_specular_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
- randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ DisneySpecularBsdf *bsdf = alloc(sd, path_flag, weight);
+ sd->flag |= (bsdf) ? bsdf_disney_specular_setup(bsdf) : 0;
}
};
-ClosureParam *bsdf_disney_specular_params()
+ClosureParam *closure_bsdf_disney_specular_params()
{
static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.N),
- CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.T),
- CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.color0), // base color
- CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data0), // metallic
- CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data1), // specular
- CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data2), // specularTint
- CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data3), // roughness
- CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data4), // anisotropic
+ CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->T),
+ CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->baseColor),
+ CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.metallic),
+ CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specular),
+ CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specularTint),
+ CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.roughness),
+ CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.anisotropic),
CLOSURE_STRING_KEYPARAM(DisneySpecularClosure, label, "label"),
CLOSURE_FINISH_PARAM(DisneySpecularClosure)
};
return params;
}
+CCLOSURE_PREPARE(closure_bsdf_disney_specular_prepare, DisneySpecularClosure);
-CCLOSURE_PREPARE(bsdf_disney_specular_prepare, DisneySpecularClosure)
-*/
/* Registration */
@@ -487,7 +477,7 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
register_closure(ss, "disney_sheen", id++,
bsdf_disney_sheen_params(), bsdf_disney_sheen_prepare);
register_closure(ss, "disney_specular", id++,
- bsdf_disney_specular_params(), bsdf_disney_specular_prepare);
+ closure_bsdf_disney_specular_params(), closure_bsdf_disney_specular_prepare);
register_closure(ss, "disney_clearcoat", id++,
bsdf_disney_clearcoat_params(), bsdf_disney_clearcoat_prepare);
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index ae0ba7704aa..e924541a31d 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -62,6 +62,7 @@ OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params();
+OSL::ClosureParam *closure_bsdf_disney_specular_params();
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
@@ -83,6 +84,7 @@ void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_disney_specular_prepare(OSL::RendererServices *, int id, void *data);
#define CCLOSURE_PREPARE(name, classname) \
void name(RendererServices *, int id, void *data) \
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index dada2a0786f..d3ed0bd1982 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -265,7 +265,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->extra->color = baseColor;
/* setup bsdf */
- if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
+ if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && roughness > 0.075f)
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf, true);
else
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true);
@@ -284,27 +284,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float3 cspec0 = baseColor * specularTint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint);
bool frontfacing = (ccl_fetch(sd, flag) & SD_BACKFACING) == 0;
- if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) {
- 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;
+ if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) {
+ float refl_roughness = roughness;
+ if (roughness <= 1e-2f)
+ refl_roughness = 0.0f;
- bsdf->extra->color = baseColor;
- bsdf->extra->cspec0 = cspec0;
-
- /* setup bsdf */
- ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing);
- }
- }
- else {
/* reflection */
#ifdef __CAUSTICS_TRICKS__
if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
@@ -317,14 +301,17 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->N = N;
bsdf->extra = extra;
- bsdf->alpha_x = roughness * roughness;
- bsdf->alpha_y = roughness * roughness;
+ bsdf->alpha_x = refl_roughness * refl_roughness;
+ bsdf->alpha_y = refl_roughness * refl_roughness;
bsdf->ior = ior;
bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0;
- ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true);
+ if (refl_roughness == 0.0f)
+ ccl_fetch(sd, flag) |= bsdf_reflection_setup(bsdf, true);
+ else
+ ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true);
}
}
@@ -333,14 +320,17 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
#endif
{
- MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*(1.0f - fresnel));
+ MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), baseColor*glass_weight*(1.0f - fresnel));
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
- refraction_roughness = 1.0f - (1.0f - roughness) * (1.0f - refraction_roughness);
+ if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
+ refraction_roughness = roughness;
+ else
+ 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;
@@ -349,10 +339,30 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0;
- ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf, true);
+ ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
}
}
+ 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);
+ }
+ }
}
#ifdef __CAUSTICS_TRICKS__
}