[Bf-blender-cvs] [a654512] master: Cycles: Implement preliminary test for volume stack update from SSS

Sergey Sharybin noreply at git.blender.org
Fri Oct 3 10:55:24 CEST 2014


Commit: a65451235637514abaaf2b04c5a89f14a6edd96f
Author: Sergey Sharybin
Date:   Fri Oct 3 10:52:04 2014 +0200
Branches: master
https://developer.blender.org/rBa65451235637514abaaf2b04c5a89f14a6edd96f

Cycles: Implement preliminary test for volume stack update from SSS

This adds an AABB collision check for objects with volumes and if there's a
collision detected then the object will have SD_OBJECT_INTERSECTS_VOLUME flag.

This solves a speed regression introduced by the fix for T39823 by skipping
volume stack update in cases no volumes intersects the current SSS object.

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

M	intern/cycles/device/device_memory.h
M	intern/cycles/kernel/kernel_path.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/object.cpp

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

diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 8eee6a2..07a6eb3 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -260,6 +260,11 @@ public:
 		return data.size();
 	}
 
+	T* get_data()
+	{
+		return &data[0];
+	}
+
 private:
 	array<T> data;
 };
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 29077a8..e68a837 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -411,6 +411,8 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd
 		int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
 #ifdef __VOLUME__
 		Ray volume_ray = *ray;
+		bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+		                                sd->flag & SD_OBJECT_INTERSECTS_VOLUME;
 #endif
 
 		/* compute lighting with the BSDF closure */
@@ -430,7 +432,7 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd
 #endif
 
 #ifdef __VOLUME__
-				if(kernel_data.integrator.use_volumes) {
+				if(need_update_volume_stack) {
 					/* Setup ray from previous surface point to the new one. */
 					volume_ray.D = normalize_len(hit_ray.P - volume_ray.P,
 					                             &volume_ray.t);
@@ -802,6 +804,8 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
 			int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, true);
 #ifdef __VOLUME__
 			Ray volume_ray = *ray;
+			bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+			                                sd->flag & SD_OBJECT_INTERSECTS_VOLUME;
 #endif
 
 			/* compute lighting with the BSDF closure */
@@ -811,7 +815,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
 				path_state_branch(&hit_state, j, num_samples);
 
 #ifdef __VOLUME__
-				if(kernel_data.integrator.use_volumes) {
+				if(need_update_volume_stack) {
 					/* Setup ray from previous surface point to the new one. */
 					float3 P = ray_offset(bssrdf_sd[hit].P, -bssrdf_sd[hit].Ng);
 					volume_ray.D = normalize_len(P - volume_ray.P,
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 34585ad..2fe1cd8 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -616,9 +616,11 @@ enum ShaderDataFlag {
 	SD_TRANSFORM_APPLIED = 2097152,		/* vertices have transform applied */
 	SD_NEGATIVE_SCALE_APPLIED = 4194304,	/* vertices have negative scale applied */
 	SD_OBJECT_HAS_VOLUME = 8388608,		/* object has a volume shader */
+	SD_OBJECT_INTERSECTS_VOLUME = 16777216, /* object intersects AABB of an object with volume shader */
 
 	SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED|
-	                   SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME)
+	                   SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME|
+	                   SD_OBJECT_INTERSECTS_VOLUME)
 };
 
 struct KernelGlobals;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index cc141b7..db6311c 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1105,8 +1105,37 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
 	bool motion_blur = false;
 #endif
 
-	foreach(Object *object, scene->objects)
+	/* TODO(sergey): There's an ongoing fake cyclic dependency between objects
+	 * and meshes here -- needs to make update functions a bit more granular in
+	 * order to keep all the updates in a logical way.
+	 */
+
+	/* update obejcts */
+	vector<Object *> volume_objects;
+	foreach(Object *object, scene->objects) {
 		object->compute_bounds(motion_blur);
+		if(object->mesh->has_volume) {
+			volume_objects.push_back(object);
+		}
+	}
+
+	int object_index = 0;
+	uint *object_flags = dscene->object_flag.get_data();
+	foreach(Object *object, scene->objects) {
+		foreach(Object *volume_object, volume_objects) {
+			if(object == volume_object) {
+				continue;
+			}
+			if(object->bounds.intersects(volume_object->bounds)) {
+				object_flags[object_index] |= SD_OBJECT_INTERSECTS_VOLUME;
+				break;
+			}
+		}
+		++object_index;
+	}
+
+	/* allocate object flag */
+	device->tex_alloc("__object_flag", dscene->object_flag);
 
 	if(progress.get_cancel()) return;
 
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 634d040..986a36b 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -75,8 +75,14 @@ void Object::compute_bounds(bool motion_blur)
 			bounds.grow(mbounds.transformed(&ttfm));
 		}
 	}
-	else
-		bounds = mbounds.transformed(&tfm);
+	else {
+		if(mesh->transform_applied) {
+			bounds = mbounds;
+		}
+		else {
+			bounds = mbounds.transformed(&tfm);
+		}
+	}
 }
 
 void Object::apply_transform(bool apply_to_motion)
@@ -410,9 +416,6 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
 		progress.set_status("Updating Objects", "Applying Static Transformations");
 		apply_static_transforms(dscene, scene, object_flag, progress);
 	}
-
-	/* allocate object flag */
-	device->tex_alloc("__object_flag", dscene->object_flag);
 }
 
 void ObjectManager::device_free(Device *device, DeviceScene *dscene)




More information about the Bf-blender-cvs mailing list