[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45245] trunk/blender/intern/cycles: Fix #30551: cycles passes combining did not always give identical result combined

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Mar 28 14:18:17 CEST 2012


Revision: 45245
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45245
Author:   blendix
Date:     2012-03-28 12:18:12 +0000 (Wed, 28 Mar 2012)
Log Message:
-----------
Fix #30551: cycles passes combining did not always give identical result combined
with antialiasing/defocus, now divide out color at the very end instead of for each
sample.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/kernel_accumulate.h
    trunk/blender/intern/cycles/kernel/kernel_passes.h
    trunk/blender/intern/cycles/render/buffers.cpp
    trunk/blender/intern/cycles/render/film.cpp
    trunk/blender/intern/cycles/render/film.h
    trunk/blender/intern/cycles/util/util_math.h

Modified: trunk/blender/intern/cycles/kernel/kernel_accumulate.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_accumulate.h	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/kernel/kernel_accumulate.h	2012-03-28 12:18:12 UTC (rev 45245)
@@ -266,17 +266,6 @@
 #endif
 }
 
-__device_inline float3 safe_divide_color(float3 a, float3 b)
-{
-	float x, y, z;
-
-	x = (b.x != 0.0f)? a.x/b.x: 0.0f;
-	y = (b.y != 0.0f)? a.y/b.y: 0.0f;
-	z = (b.z != 0.0f)? a.z/b.z: 0.0f;
-
-	return make_float3(x, y, z);
-}
-
 __device_inline float3 path_radiance_sum(PathRadiance *L)
 {
 #ifdef __PASSES__

Modified: trunk/blender/intern/cycles/kernel/kernel_passes.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_passes.h	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/kernel/kernel_passes.h	2012-03-28 12:18:12 UTC (rev 45245)
@@ -94,30 +94,18 @@
 	if(!kernel_data.film.use_light_pass)
 		return;
 	
-	if(flag & PASS_DIFFUSE_INDIRECT) {
-		float3 color = safe_divide_color(L->indirect_diffuse, L->color_diffuse);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, color);
-	}
-	if(flag & PASS_GLOSSY_INDIRECT) {
-		float3 color = safe_divide_color(L->indirect_glossy, L->color_glossy);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, color);
-	}
-	if(flag & PASS_TRANSMISSION_INDIRECT) {
-		float3 color = safe_divide_color(L->indirect_transmission, L->color_transmission);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, color);
-	}
-	if(flag & PASS_DIFFUSE_DIRECT) {
-		float3 color = safe_divide_color(L->direct_diffuse, L->color_diffuse);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, color);
-	}
-	if(flag & PASS_GLOSSY_DIRECT) {
-		float3 color = safe_divide_color(L->direct_glossy, L->color_glossy);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, color);
-	}
-	if(flag & PASS_TRANSMISSION_DIRECT) {
-		float3 color = safe_divide_color(L->direct_transmission, L->color_transmission);
-		kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, color);
-	}
+	if(flag & PASS_DIFFUSE_INDIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, L->indirect_diffuse);
+	if(flag & PASS_GLOSSY_INDIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, L->indirect_glossy);
+	if(flag & PASS_TRANSMISSION_INDIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, L->indirect_transmission);
+	if(flag & PASS_DIFFUSE_DIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, L->direct_diffuse);
+	if(flag & PASS_GLOSSY_DIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, L->direct_glossy);
+	if(flag & PASS_TRANSMISSION_DIRECT)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, L->direct_transmission);
 
 	if(flag & PASS_EMISSION)
 		kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);

Modified: trunk/blender/intern/cycles/render/buffers.cpp
===================================================================
--- trunk/blender/intern/cycles/render/buffers.cpp	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/render/buffers.cpp	2012-03-28 12:18:12 UTC (rev 45245)
@@ -173,14 +173,38 @@
 		else if(components == 3) {
 			assert(pass.components == 4);
 
-			/* RGB/vector */
-			for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
-				float3 f = make_float3(in[0], in[1], in[2]);
+			if(pass.divide_type != PASS_NONE) {
+				/* RGB lighting passes that need to divide out color */
+				pass_offset = 0;
+				foreach(Pass& color_pass, params.passes) {
+					if(color_pass.type == pass.divide_type)
+						break;
+					pass_offset += color_pass.components;
+				}
 
-				pixels[0] = f.x*scale_exposure;
-				pixels[1] = f.y*scale_exposure;
-				pixels[2] = f.z*scale_exposure;
+				float *in_divide = (float*)buffer.data_pointer + pass_offset;
+
+				for(int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
+					float3 f = make_float3(in[0], in[1], in[2]);
+					float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
+
+					f = safe_divide_color(f*exposure, f_divide);
+
+					pixels[0] = f.x;
+					pixels[1] = f.y;
+					pixels[2] = f.z;
+				}
 			}
+			else {
+				/* RGB/vector */
+				for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+					float3 f = make_float3(in[0], in[1], in[2]);
+
+					pixels[0] = f.x*scale_exposure;
+					pixels[1] = f.y*scale_exposure;
+					pixels[2] = f.z*scale_exposure;
+				}
+			}
 		}
 		else if(components == 4) {
 			assert(pass.components == components);

Modified: trunk/blender/intern/cycles/render/film.cpp
===================================================================
--- trunk/blender/intern/cycles/render/film.cpp	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/render/film.cpp	2012-03-28 12:18:12 UTC (rev 45245)
@@ -38,11 +38,16 @@
 
 void Pass::add(PassType type, vector<Pass>& passes)
 {
+	foreach(Pass& existing_pass, passes)
+		if(existing_pass.type == type)
+			return;
+
 	Pass pass;
 
 	pass.type = type;
 	pass.filter = true;
 	pass.exposure = false;
+	pass.divide_type = PASS_NONE;
 
 	switch(type) {
 		case PASS_NONE:
@@ -82,26 +87,32 @@
 		case PASS_DIFFUSE_INDIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_DIFFUSE_COLOR;
 			break;
 		case PASS_GLOSSY_INDIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_GLOSSY_COLOR;
 			break;
 		case PASS_TRANSMISSION_INDIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_TRANSMISSION_COLOR;
 			break;
 		case PASS_DIFFUSE_DIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_DIFFUSE_COLOR;
 			break;
 		case PASS_GLOSSY_DIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_GLOSSY_COLOR;
 			break;
 		case PASS_TRANSMISSION_DIRECT:
 			pass.components = 4;
 			pass.exposure = true;
+			pass.divide_type = PASS_TRANSMISSION_COLOR;
 			break;
 
 		case PASS_EMISSION:
@@ -127,6 +138,9 @@
 	/* order from by components, to ensure alignment so passes with size 4
 	   come first and then passes with size 1 */
 	sort(passes.begin(), passes.end(), compare_pass_order);
+
+	if(pass.divide_type != PASS_NONE)
+		Pass::add(pass.divide_type, passes);
 }
 
 bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)

Modified: trunk/blender/intern/cycles/render/film.h
===================================================================
--- trunk/blender/intern/cycles/render/film.h	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/render/film.h	2012-03-28 12:18:12 UTC (rev 45245)
@@ -36,6 +36,7 @@
 	int components;
 	bool filter;
 	bool exposure;
+	PassType divide_type;
 
 	static void add(PassType type, vector<Pass>& passes);
 	static bool equals(const vector<Pass>& A, const vector<Pass>& B);

Modified: trunk/blender/intern/cycles/util/util_math.h
===================================================================
--- trunk/blender/intern/cycles/util/util_math.h	2012-03-28 11:53:18 UTC (rev 45244)
+++ trunk/blender/intern/cycles/util/util_math.h	2012-03-28 12:18:12 UTC (rev 45245)
@@ -799,6 +799,19 @@
 	*b = cross(N, *a);
 }
 
+/* Color division */
+
+__device_inline float3 safe_divide_color(float3 a, float3 b)
+{
+	float x, y, z;
+
+	x = (b.x != 0.0f)? a.x/b.x: 0.0f;
+	y = (b.y != 0.0f)? a.y/b.y: 0.0f;
+	z = (b.z != 0.0f)? a.z/b.z: 0.0f;
+
+	return make_float3(x, y, z);
+}
+
 CCL_NAMESPACE_END
 
 #endif /* __UTIL_MATH_H__ */




More information about the Bf-blender-cvs mailing list