[Bf-blender-cvs] [3cd5eb5] cycles_disney_brdf: Fixed a bug in the Disney BSDF that caused specular reflections to be too bright and diffuse is now reacting to the roughness again

Pascal Schoen noreply at git.blender.org
Tue Sep 27 11:22:32 CEST 2016


Commit: 3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd
Author: Pascal Schoen
Date:   Fri Sep 16 08:47:56 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rB3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd

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

===================================================================

M	intern/cycles/kernel/closure/bsdf_disney_specular.h
M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_reflection.h
M	intern/cycles/kernel/closure/bssrdf.h
M	intern/cycles/kernel/osl/osl_closures.cpp
M	intern/cycles/kernel/osl/osl_closures.h
M	intern/cycles/kernel/svm/svm_closure.h

===================================================================

diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h
index 7e8139f..b83bb29 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_specular.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h
@@ -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;
                 }
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 9ab9b17..6c2f295 100644
--- a/i

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list