[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