[Bf-blender-cvs] [faa10d1] master: Cycles: optimization of panoramic camera in volume

Sergey Sharybin noreply at git.blender.org
Thu Oct 2 20:45:32 CEST 2014


Commit: faa10d1ced8ec74319f0acbd2d789345beced008
Author: Sergey Sharybin
Date:   Thu Oct 2 20:37:05 2014 +0200
Branches: master
https://developer.blender.org/rBfaa10d1ced8ec74319f0acbd2d789345beced008

Cycles: optimization of panoramic camera in volume

Now we do much better preliminary check for panoramic camera is inside the
volume object boundings.

Also we're now cacheing the has_volume in the mesh, which makes it unneeded
iterations for each object's shaders.

Should be no functional changes, just faster sync and panoramic-in-volume
rendering.

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

M	intern/cycles/render/camera.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h

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

diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 4c73726..28b6c99 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -26,32 +26,6 @@
 
 CCL_NAMESPACE_BEGIN
 
-namespace {
-
-bool object_has_volume(Scene *scene, Object *object)
-{
-	Mesh *mesh = object->mesh;
-	foreach(uint shader, mesh->used_shaders) {
-		if(scene->shaders[shader]->has_volume) {
-			return true;
-		}
-	}
-	return false;
-}
-
-bool scene_has_volume(Scene *scene)
-{
-	for(size_t i = 0; i < scene->objects.size(); ++i) {
-		Object *object = scene->objects[i];
-		if(object_has_volume(scene, object)) {
-			return true;
-		}
-	}
-	return false;
-}
-
-}  // namespace
-
 Camera::Camera()
 {
 	shuttertime = 1.0f;
@@ -303,33 +277,15 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
 	/* Camera in volume. */
 	kcam->is_inside_volume = 0;
 	if(use_camera_in_volume) {
-		if(type == CAMERA_PANORAMA) {
-			/* It's not clear how to do viewplace->object intersection for
-			 * panoramic cameras, for now let's just check for whether there
-			 * are any volumes in the scene.
-			 */
-			kcam->is_inside_volume = scene_has_volume(scene);
-		}
-		else {
-			/* TODO(sergey): Whole bunch of stuff here actually:
-			 * - We do rather stupid check with object AABB to camera viewplane
-			 *   AABB intersection, which is quite fast to perform, but which
-			 *   could give some false-positives checks here, More grained check
-			 *   would help avoiding time wasted n the kernel to initialize the
-			 *   volume stack.
-			 * - We could cache has_volume in the cache, would save quite a few
-			 *   CPU ticks when having loads of instanced meshes.
-			 */
-			BoundBox viewplane_boundbox = viewplane_bounds_get();
-			for(size_t i = 0; i < scene->objects.size(); ++i) {
-				Object *object = scene->objects[i];
-				if(object_has_volume(scene, object)) {
-					if(viewplane_boundbox.intersects(object->bounds)) {
-						/* TODO(sergey): Consider adding more grained check. */
-						kcam->is_inside_volume = 1;
-						break;
-					}
-				}
+		BoundBox viewplane_boundbox = viewplane_bounds_get();
+		for(size_t i = 0; i < scene->objects.size(); ++i) {
+			Object *object = scene->objects[i];
+			if(object->mesh->has_volume &&
+			   viewplane_boundbox.intersects(object->bounds))
+			{
+				/* TODO(sergey): Consider adding more grained check. */
+				kcam->is_inside_volume = 1;
+				break;
 			}
 		}
 	}
@@ -408,21 +364,27 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
 
 BoundBox Camera::viewplane_bounds_get()
 {
-	assert(type != CAMERA_PANORAMA);
-
 	/* TODO(sergey): This is all rather stupid, but is there a way to perform
 	 * checks we need in a more clear and smart fasion?
 	 */
 	BoundBox bounds = BoundBox::empty;
-	bounds.grow(transform_raster_to_world(0.0f, 0.0f));
-	bounds.grow(transform_raster_to_world(0.0f, (float)height));
-	bounds.grow(transform_raster_to_world((float)width, (float)height));
-	bounds.grow(transform_raster_to_world((float)width, 0.0f));
-	if(type == CAMERA_PERSPECTIVE) {
-		/* Center point has the most distancei in local Z axis,
-		 * use it to construct bounding box/
-		 */
-		bounds.grow(transform_raster_to_world(0.5f*width, 0.5f*height));
+
+	if(type == CAMERA_PANORAMA) {
+		bounds.grow(make_float3(cameratoworld.w.x,
+		                        cameratoworld.w.y,
+		                        cameratoworld.w.z));
+	}
+	else {
+		bounds.grow(transform_raster_to_world(0.0f, 0.0f));
+		bounds.grow(transform_raster_to_world(0.0f, (float)height));
+		bounds.grow(transform_raster_to_world((float)width, (float)height));
+		bounds.grow(transform_raster_to_world((float)width, 0.0f));
+		if(type == CAMERA_PERSPECTIVE) {
+			/* Center point has the most distancei in local Z axis,
+			 * use it to construct bounding box/
+			 */
+			bounds.grow(transform_raster_to_world(0.5f*width, 0.5f*height));
+		}
 	}
 	return bounds;
 }
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 5602609..54cfab4 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1034,9 +1034,14 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
 
 	/* update normals */
 	foreach(Mesh *mesh, scene->meshes) {
-		foreach(uint shader, mesh->used_shaders)
+		mesh->has_volume = false;
+		foreach(uint shader, mesh->used_shaders) {
 			if(scene->shaders[shader]->need_update_attributes)
 				mesh->need_update = true;
+			if(scene->shaders[shader]->has_volume) {
+				mesh->has_volume = true;
+			}
+		}
 
 		if(mesh->need_update) {
 			mesh->add_face_normals();
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 28cee57..7e34b76 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -79,6 +79,8 @@ public:
 	vector<uint> shader;
 	vector<bool> smooth;
 
+	bool has_volume;  /* Set in the device_update(). */
+
 	vector<float4> curve_keys; /* co + radius */
 	vector<Curve> curves;




More information about the Bf-blender-cvs mailing list