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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
DisneySpecularBsdf params;
|
||||
|
||||
void setup()
|
||||
DisneySpecularBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
|
||||
{
|
||||
sc.prim = this;
|
||||
m_shaderdata_flag = bsdf_disney_specular_setup(&sc);
|
||||
if (!skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
|
||||
DisneySpecularBsdf *bsdf = (DisneySpecularBsdf*)bsdf_alloc_osl(sd, sizeof(DisneySpecularBsdf), weight, ¶ms);
|
||||
DisneySpecularExtra *extra = (DisneySpecularExtra*)closure_alloc_extra(sd, sizeof(DisneySpecularExtra));
|
||||
if (bsdf && extra) {
|
||||
bsdf->extra = extra;
|
||||
return bsdf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void blur(float roughness)
|
||||
void setup(ShaderData *sd, int path_flag, float3 weight)
|
||||
{
|
||||
}
|
||||
|
||||
float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
|
||||
{
|
||||
return bsdf_disney_specular_eval_reflect(&sc, omega_out, omega_in, &pdf);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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,7 +284,66 @@ 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) {
|
||||
if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) {
|
||||
float refl_roughness = roughness;
|
||||
if (roughness <= 1e-2f)
|
||||
refl_roughness = 0.0f;
|
||||
|
||||
/* reflection */
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
|
||||
#endif
|
||||
{
|
||||
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel);
|
||||
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
|
||||
|
||||
if (bsdf && extra) {
|
||||
bsdf->N = N;
|
||||
bsdf->extra = extra;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* refraction */
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
bsdf->ior = ior;
|
||||
|
||||
bsdf->extra->color = baseColor;
|
||||
bsdf->extra->cspec0 = cspec0;
|
||||
|
||||
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));
|
||||
|
||||
@@ -304,55 +363,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel);
|
||||
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
|
||||
|
||||
if (bsdf && extra) {
|
||||
bsdf->N = N;
|
||||
bsdf->extra = extra;
|
||||
|
||||
bsdf->alpha_x = roughness * roughness;
|
||||
bsdf->alpha_y = roughness * roughness;
|
||||
bsdf->ior = ior;
|
||||
|
||||
bsdf->extra->color = baseColor;
|
||||
bsdf->extra->cspec0 = cspec0;
|
||||
|
||||
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* refraction */
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
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));
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user