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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-03 02:05:57 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-03 02:05:57 +0400
commit273f5226da53654039bddbf94210c458cfcc1e71 (patch)
treedf3cb977c8e42b253def6afa9c29ed2c356b0fd2
parent91ba6c9ced2a95105fab8616ba6c41a55e1b4b1f (diff)
Fix #35160: cycles was rendering glossy BSDF's with zero roughness too rough
after a bugfix for precision issues with low roughness. Now it renders them as perfectly sharp which avoids the problematic calculations rather than increasing the roughness.
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h223
1 files changed, 126 insertions, 97 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index b771e02f131..c586c1e3311 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -46,7 +46,7 @@ __device int bsdf_microfacet_ggx_setup(ShaderClosure *sc)
{
float ag = sc->data0;
- float m_ag = clamp(ag, 1e-3f, 1.0f);
+ float m_ag = clamp(ag, 0.0f, 1.0f);
sc->data0 = m_ag;
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
@@ -59,7 +59,7 @@ __device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
float ag = sc->data0;
float eta = sc->data1;
- float m_ag = clamp(ag, 1e-3f, 1.0f);
+ float m_ag = clamp(ag, 0.0f, 1.0f);
float m_eta = eta;
sc->data0 = m_ag;
@@ -82,7 +82,8 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 N = sc->N;
- if(m_refractive) return make_float3 (0, 0, 0);
+ if(m_refractive || m_ag <= 1e-4f)
+ return make_float3 (0, 0, 0);
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
if(cosNI > 0 && cosNO > 0) {
@@ -119,7 +120,8 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 N = sc->N;
- if(!m_refractive) return make_float3 (0, 0, 0);
+ if(!m_refractive || m_ag <= 1e-4f)
+ return make_float3 (0, 0, 0);
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
@@ -176,26 +178,33 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
// eq. 39 - compute actual reflected direction
*omega_in = 2 * cosMO * m - I;
if(dot(Ng, *omega_in) > 0) {
- // microfacet normal is visible to this ray
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- *pdf = pm * 0.25f / cosMO;
- // eval BRDF*cosNI
- float cosNI = dot(N, *omega_in);
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- // eq. 20: (F*G*D)/(4*in*on)
- float out = (G * D) * 0.25f / cosNO;
- *eval = make_float3(out, out, out);
+ if (m_ag <= 1e-4f) {
+ *pdf = 1;
+ *eval = make_float3(1, 1, 1);
+ }
+ else {
+ // microfacet normal is visible to this ray
+ // eq. 33
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ // eq. 24
+ float pm = D * cosThetaM;
+ // convert into pdf of the sampled direction
+ // eq. 38 - but see also:
+ // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ *pdf = pm * 0.25f / cosMO;
+ // eval BRDF*cosNI
+ float cosNI = dot(N, *omega_in);
+ // eq. 34: now calculate G1(i,m) and G1(o,m)
+ float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ float G = G1o * G1i;
+ // eq. 20: (F*G*D)/(4*in*on)
+ float out = (G * D) * 0.25f / cosNO;
+ *eval = make_float3(out, out, out);
+ }
+
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
@@ -224,27 +233,34 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
*domega_in_dx = dTdx;
*domega_in_dy = dTdy;
#endif
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 24
- float pm = D * cosThetaM;
- // eval BRDF*cosNI
- float cosNI = dot(N, *omega_in);
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- // eq. 21
- float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, I);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
- // eq. 38 and eq. 17
- *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
- *eval = make_float3(out, out, out);
+
+ if (m_ag <= 1e-4f) {
+ *pdf = 1;
+ *eval = make_float3(1, 1, 1);
+ }
+ else {
+ // eq. 33
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ // eq. 24
+ float pm = D * cosThetaM;
+ // eval BRDF*cosNI
+ float cosNI = dot(N, *omega_in);
+ // eq. 34: now calculate G1(i,m) and G1(o,m)
+ float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ float G = G1o * G1i;
+ // eq. 21
+ float cosHI = dot(m, *omega_in);
+ float cosHO = dot(m, I);
+ float Ht2 = m_eta * cosHI + cosHO;
+ Ht2 *= Ht2;
+ float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
+ // eq. 38 and eq. 17
+ *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
+ *eval = make_float3(out, out, out);
+ }
}
}
}
@@ -256,7 +272,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
__device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc)
{
float ab = sc->data0;
- float m_ab = clamp(ab, 1e-3f, 1.0f);
+ float m_ab = clamp(ab, 0.0f, 1.0f);
sc->data0 = m_ab;
@@ -268,7 +284,7 @@ __device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
{
float ab = sc->data0;
float eta = sc->data1;
- float m_ab = clamp(ab, 1e-3f, 1.0f);
+ float m_ab = clamp(ab, 0.0f, 1.0f);
float m_eta = eta;
sc->data0 = m_ab;
@@ -291,7 +307,8 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, c
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 N = sc->N;
- if(m_refractive) return make_float3 (0, 0, 0);
+ if(m_refractive || m_ab <= 1e-4f)
+ return make_float3 (0, 0, 0);
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
@@ -330,7 +347,8 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc,
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 N = sc->N;
- if(!m_refractive) return make_float3 (0, 0, 0);
+ if(!m_refractive || m_ab <= 1e-4f)
+ return make_float3 (0, 0, 0);
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
@@ -390,29 +408,35 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
// eq. 39 - compute actual reflected direction
*omega_in = 2 * cosMO * m - I;
if(dot(Ng, *omega_in) > 0) {
- // microfacet normal is visible to this ray
- // eq. 25
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = tanThetaM * tanThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- *pdf = pm * 0.25f / cosMO;
- // Eval BRDF*cosNI
- float cosNI = dot(N, *omega_in);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (safe_sqrtf(alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (safe_sqrtf(alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- // eq. 20: (F*G*D)/(4*in*on)
- float out = (G * D) * 0.25f / cosNO;
- *eval = make_float3(out, out, out);
+ if (m_ab <= 1e-4f) {
+ *pdf = 1;
+ *eval = make_float3(1, 1, 1);
+ }
+ else {
+ // microfacet normal is visible to this ray
+ // eq. 25
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = tanThetaM * tanThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+ // eq. 24
+ float pm = D * cosThetaM;
+ // convert into pdf of the sampled direction
+ // eq. 38 - but see also:
+ // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ *pdf = pm * 0.25f / cosMO;
+ // Eval BRDF*cosNI
+ float cosNI = dot(N, *omega_in);
+ // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
+ float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
+ float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+ float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
+ float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
+ float G = G1o * G1i;
+ // eq. 20: (F*G*D)/(4*in*on)
+ float out = (G * D) * 0.25f / cosNO;
+ *eval = make_float3(out, out, out);
+ }
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
@@ -441,31 +465,36 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
*domega_in_dx = dTdx;
*domega_in_dy = dTdy;
#endif
-
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = tanThetaM * tanThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
- // eq. 24
- float pm = D * cosThetaM;
- // eval BRDF*cosNI
- float cosNI = dot(N, *omega_in);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (safe_sqrtf(alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (safe_sqrtf(alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- // eq. 21
- float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, I);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
- // eq. 38 and eq. 17
- *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
- *eval = make_float3(out, out, out);
+ if (m_ab <= 1e-4f) {
+ *pdf = 1;
+ *eval = make_float3(1, 1, 1);
+ }
+ else {
+ // eq. 33
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = tanThetaM * tanThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+ // eq. 24
+ float pm = D * cosThetaM;
+ // eval BRDF*cosNI
+ float cosNI = dot(N, *omega_in);
+ // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
+ float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
+ float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+ float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
+ float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
+ float G = G1o * G1i;
+ // eq. 21
+ float cosHI = dot(m, *omega_in);
+ float cosHO = dot(m, I);
+ float Ht2 = m_eta * cosHI + cosHO;
+ Ht2 *= Ht2;
+ float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
+ // eq. 38 and eq. 17
+ *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
+ *eval = make_float3(out, out, out);
+ }
}
}
}