Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-10-02 22:37:05 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-10-02 22:45:30 +0400
commitfaa10d1ced8ec74319f0acbd2d789345beced008 (patch)
treedd50a0c8ff2f41d77252ba1a33c7465bb7be982d /intern
parente64ecaea4a93274147a6e5fc36a44ed42a7cd27f (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/render/camera.cpp90
-rw-r--r--intern/cycles/render/mesh.cpp7
-rw-r--r--intern/cycles/render/mesh.h2
3 files changed, 34 insertions, 65 deletions
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 4c73726ba33..28b6c994568 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 5602609c030..54cfab42a97 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 28cee5745ea..7e34b761faf 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;