[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45448] trunk/blender/intern/cycles/kernel /svm/bsdf_microfacet.h: Cycles: fix nan' s generated by glossy BSDF in some cases.

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Apr 6 18:08:15 CEST 2012


Revision: 45448
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45448
Author:   blendix
Date:     2012-04-06 16:08:14 +0000 (Fri, 06 Apr 2012)
Log Message:
-----------
Cycles: fix nan's generated by glossy BSDF in some cases.

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

Modified: trunk/blender/intern/cycles/kernel/svm/bsdf_microfacet.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/bsdf_microfacet.h	2012-04-06 13:50:26 UTC (rev 45447)
+++ trunk/blender/intern/cycles/kernel/svm/bsdf_microfacet.h	2012-04-06 16:08:14 UTC (rev 45448)
@@ -43,6 +43,11 @@
 	float m_eta;
 } BsdfMicrofacetGGXClosure;
 
+__device_inline float safe_sqrtf(float f)
+{
+	return sqrtf(max(f, 0.0f));
+}
+
 __device void bsdf_microfacet_ggx_setup(ShaderData *sd, ShaderClosure *sc, float ag, float eta, bool refractive)
 {
 	float m_ag = clamp(ag, 1e-4f, 1.0f);
@@ -88,8 +93,8 @@
 		float cosThetaM4 = cosThetaM2 * cosThetaM2;
 		float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
 		// eq. 34: now calculate G1(i,m) and G1(o,m)
-		float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
-		float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
+		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;
 		float out = (G * D) * 0.25f / cosNO;
 		// eq. 24
@@ -129,8 +134,8 @@
 	float cosThetaM4 = cosThetaM2 * cosThetaM2;
 	float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
 	// eq. 34: now calculate G1(i,m) and G1(o,m)
-	float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
-	float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
+	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;
 	// probability
 	float invHt2 = 1 / dot(ht, ht);
@@ -161,8 +166,8 @@
 		//tttt  and sin(atan(x)) == x/sqrt(1+x^2)
 		float alpha2 = m_ag * m_ag;
 		float tanThetaM2 = alpha2 * randu / (1 - randu);
-		float cosThetaM  = 1 / sqrtf(1 + tanThetaM2);
-		float sinThetaM  = cosThetaM * sqrtf(tanThetaM2);
+		float cosThetaM  = 1 / safe_sqrtf(1 + tanThetaM2);
+		float sinThetaM  = cosThetaM * safe_sqrtf(tanThetaM2);
 		float phiM = 2 * M_PI_F * randv;
 		float3 m = (cosf(phiM) * sinThetaM) * X +
 				 (sinf(phiM) * sinThetaM) * Y +
@@ -187,8 +192,8 @@
 					// eval BRDF*cosNI
 					float cosNI = dot(m_N, *omega_in);
 					// eq. 34: now calculate G1(i,m) and G1(o,m)
-					float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
-					float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
+					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;
@@ -234,8 +239,8 @@
 				// eval BRDF*cosNI
 				float cosNI = dot(m_N, *omega_in);
 				// eq. 34: now calculate G1(i,m) and G1(o,m)
-				float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
-				float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
+				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);
@@ -313,8 +318,8 @@
 	   float cosThetaM4 = cosThetaM2 * cosThetaM2;
 	   float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 *  cosThetaM4);
 	   // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
-	   float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
-	   float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+	   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;
@@ -356,8 +361,8 @@
 	float cosThetaM4 = cosThetaM2 * cosThetaM2;
 	float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 *  cosThetaM4);
 	// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
-	float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
-	float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+	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;
@@ -389,8 +394,8 @@
 		// we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
 		//tttt  and sin(atan(x)) == x/sqrt(1+x^2)
 		float alpha2 = m_ab * m_ab;
-		float tanThetaM = sqrtf(-alpha2 * logf(1 - randu));
-		float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM);
+		float tanThetaM = safe_sqrtf(-alpha2 * logf(1 - randu));
+		float cosThetaM = 1 / safe_sqrtf(1 + tanThetaM * tanThetaM);
 		float sinThetaM = cosThetaM * tanThetaM;
 		float phiM = 2 * M_PI_F * randv;
 		float3 m = (cosf(phiM) * sinThetaM) * X +
@@ -418,8 +423,8 @@
 					// Eval BRDF*cosNI
 					float cosNI = dot(m_N, *omega_in);
 					// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
-					float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
-					float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+					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;
@@ -469,8 +474,8 @@
 				// eval BRDF*cosNI
 				float cosNI = dot(m_N, *omega_in);
 				// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
-				float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
-				float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
+				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;




More information about the Bf-blender-cvs mailing list