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;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to