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>2015-10-27 11:16:04 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-10-28 00:43:06 +0300
commit6a529e14f4c25fc20b797799b602472d3a22a0f9 (patch)
treed94d60107dc8540312c7f3a217e01a7f4174216e /intern
parentc07c066685658fc5a9f070ab9f9e8fb97926568a (diff)
Cycles: Support user-defined shutter curve
Previously shutter was instantly opening, staying opened for the shutter time period of time and then instantly closing. This isn't quite how real cameras are working, where shutter is opening with some curve. Now it is possible to define user curve for how much shutter is opened across the sampling period of time. This could be used for example to make motion blur trails softer.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel_camera.h9
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/render/camera.cpp50
-rw-r--r--intern/cycles/render/camera.h4
-rw-r--r--intern/cycles/render/scene.cpp2
-rw-r--r--intern/cycles/util/util_math_cdf.cpp6
6 files changed, 65 insertions, 10 deletions
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 8d439ceb0d7..01017eabde2 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -290,10 +290,13 @@ ccl_device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, f
#ifdef __CAMERA_MOTION__
/* motion blur */
- if(kernel_data.cam.shuttertime == -1.0f)
+ if(kernel_data.cam.shuttertime == -1.0f) {
ray->time = TIME_INVALID;
- else
- ray->time = time;
+ }
+ else {
+ const int shutter_table_offset = kernel_data.cam.shutter_table_offset;
+ ray->time = lookup_table_read(kg, time, shutter_table_offset, SHUTTER_TABLE_SIZE);
+ }
#endif
/* sample */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 740a5f1f5d3..1d71e6435db 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -39,6 +39,7 @@ CCL_NAMESPACE_BEGIN
#define LIGHT_SIZE 5
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
+#define SHUTTER_TABLE_SIZE 256
#define PARTICLE_SIZE 5
#define TIME_INVALID FLT_MAX
@@ -813,6 +814,9 @@ typedef struct KernelCamera {
* Used for camera zoom motion blur,
*/
PerspectiveMotionTransform perspective_motion;
+
+ int shutter_table_offset;
+ int pad;
} KernelCamera;
typedef struct KernelFilm {
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);
diff --git a/intern/cycles/util/util_math_cdf.cpp b/intern/cycles/util/util_math_cdf.cpp
index cafe4c5abeb..ec78ca15d88 100644
--- a/intern/cycles/util/util_math_cdf.cpp
+++ b/intern/cycles/util/util_math_cdf.cpp
@@ -37,7 +37,7 @@ void util_cdf_invert(const int resolution,
float x = i / (float)half_size;
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
float t;
- if(index < cdf.size()) {
+ if(index < cdf.size() - 1) {
t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
} else {
t = 0.0f;
@@ -49,11 +49,11 @@ void util_cdf_invert(const int resolution,
}
}
else {
- for(int i = 0; i <= resolution; i++) {
+ for(int i = 0; i < resolution; i++) {
float x = from + range * (float)i * inv_resolution;
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
float t;
- if(index < cdf.size()) {
+ if(index < cdf.size() - 1) {
t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
} else {
t = 0.0f;