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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-10-03 12:52:04 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-10-03 12:52:04 +0400
commita65451235637514abaaf2b04c5a89f14a6edd96f (patch)
tree434aa96d50837b2a08992230ddb46f9ab1995be4
parentb86f199a98fe77b634ea7f686d3d664d9791562b (diff)
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.
-rw-r--r--intern/cycles/device/device_memory.h5
-rw-r--r--intern/cycles/kernel/kernel_path.h8
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/render/mesh.cpp31
-rw-r--r--intern/cycles/render/object.cpp13
5 files changed, 52 insertions, 9 deletions
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 8eee6a2c79e..07a6eb36a3c 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 29077a8886c..e68a8370012 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 34585ad8de6..2fe1cd87072 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 cc141b771d1..db6311c3d97 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 634d0401aa9..986a36ba120 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)