diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/camera.cpp | 50 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 4 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 2 |
3 files changed, 52 insertions, 4 deletions
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 88ff7fbb70a..c59971996bc 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -18,18 +18,36 @@ #include "mesh.h" #include "object.h" #include "scene.h" +#include "tables.h" #include "device.h" #include "util_foreach.h" +#include "util_function.h" +#include "util_math_cdf.h" #include "util_vector.h" CCL_NAMESPACE_BEGIN +static float shutter_curve_eval(float x, + float shutter_curve[RAMP_TABLE_SIZE]) +{ + x *= RAMP_TABLE_SIZE; + int index = (int)x; + float frac = x - index; + if(index < RAMP_TABLE_SIZE - 1) { + return lerp(shutter_curve[index], shutter_curve[index + 1], frac); + } + else { + return shutter_curve[RAMP_TABLE_SIZE - 1]; + } +} + Camera::Camera() { shuttertime = 1.0f; motion_position = MOTION_POSITION_CENTER; + shutter_table_offset = TABLE_OFFSET_INVALID; aperturesize = 0.0f; focaldistance = 10.0f; @@ -85,6 +103,12 @@ Camera::Camera() need_device_update = true; need_flags_update = true; previous_need_motion = -1; + + /* Initialize shutter curve. */ + const int num_shutter_points = sizeof(shutter_curve) / sizeof(*shutter_curve); + for(int i = 0; i < num_shutter_points; ++i) { + shutter_curve[i] = 1.0f; + } } Camera::~Camera() @@ -279,6 +303,23 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) /* motion blur */ #ifdef __CAMERA_MOTION__ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f; + + if(need_motion == Scene::MOTION_BLUR) { + vector<float> shutter_table; + util_cdf_inverted(SHUTTER_TABLE_SIZE, + 0.0f, + 1.0f, + function_bind(shutter_curve_eval, _1, shutter_curve), + false, + shutter_table); + shutter_table_offset = scene->lookup_tables->add_table(dscene, + shutter_table); + kcam->shutter_table_offset = (int)shutter_table_offset; + } + else if(shutter_table_offset != TABLE_OFFSET_INVALID) { + scene->lookup_tables->remove_table(shutter_table_offset); + shutter_table_offset = TABLE_OFFSET_INVALID; + } #else kcam->shuttertime = -1.0f; #endif @@ -342,9 +383,14 @@ void Camera::device_update_volume(Device * /*device*/, need_flags_update = false; } -void Camera::device_free(Device * /*device*/, DeviceScene * /*dscene*/) +void Camera::device_free(Device * /*device*/, + DeviceScene * /*dscene*/, + Scene *scene) { - /* nothing to free, only writing to constant memory */ + if(shutter_table_offset != TABLE_OFFSET_INVALID) { + scene->lookup_tables->remove_table(shutter_table_offset); + shutter_table_offset = TABLE_OFFSET_INVALID; + } } bool Camera::modified(const Camera& cam) diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 53bd4f0bc14..1c26afafeff 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -50,6 +50,8 @@ public: /* motion blur */ float shuttertime; MotionPosition motion_position; + float shutter_curve[RAMP_TABLE_SIZE]; + size_t shutter_table_offset; /* depth of field */ float focaldistance; @@ -132,7 +134,7 @@ public: void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene); - void device_free(Device *device, DeviceScene *dscene); + void device_free(Device *device, DeviceScene *dscene, Scene *scene); bool modified(const Camera& cam); bool motion_modified(const Camera& cam); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 19d715d834b..25f812221ac 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -97,7 +97,7 @@ void Scene::free_memory(bool final) particle_systems.clear(); if(device) { - camera->device_free(device, &dscene); + camera->device_free(device, &dscene, this); film->device_free(device, &dscene, this); background->device_free(device, &dscene); integrator->device_free(device, &dscene); |