[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56478] trunk/blender/intern/cycles/kernel /closure/bsdf_microfacet.h: Fix #35160: cycles was rendering glossy BSDF' s with zero roughness too rough

Brecht Van Lommel brechtvanlommel at pandora.be
Fri May 3 00:05:58 CEST 2013


Revision: 56478
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56478
Author:   blendix
Date:     2013-05-02 22:05:57 +0000 (Thu, 02 May 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/closure/bsdf_microfacet.h

Modified: trunk/blender/intern/cycles/kernel/closure/bsdf_microfacet.h
===================================================================
--- trunk/blender/intern/cycles/kernel/closure/bsdf_microfacet.h	2013-05-02 21:27:19 UTC (rev 56477)
+++ trunk/blender/intern/cycles/kernel/closure/bsdf_microfacet.h	2013-05-02 22:05:57 UTC (rev 56478)
@@ -46,7 +46,7 @@
 {
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 				// 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 @@
 				*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_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 @@
 {
 	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 @@
 	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 @@
 	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 @@
 				// 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 @@
 				*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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list