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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-03-10 03:36:09 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-03-10 08:27:19 +0300
commit78c2063685cb6e0d0bcb895cf4eb70686455d596 (patch)
tree70f7010f9a960f087b3e5b842874a919a4e0860d /intern/cycles/render
parent267d8923265a284c5d9a462e1d86305d613fcad8 (diff)
Cycles: support arbitrary number of motion blur steps for cameras.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/camera.cpp77
-rw-r--r--intern/cycles/render/camera.h10
-rw-r--r--intern/cycles/render/object.cpp9
-rw-r--r--intern/cycles/render/scene.cpp1
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/render/session.cpp2
6 files changed, 77 insertions, 25 deletions
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index a1c6a279956..38936ffc094 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -82,6 +82,7 @@ NODE_DEFINE(Camera)
SOCKET_FLOAT(bladesrotation, "Blades Rotation", 0.0f);
SOCKET_TRANSFORM(matrix, "Matrix", transform_identity());
+ SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
SOCKET_FLOAT(aperture_ratio, "Aperture Ratio", 1.0f);
@@ -151,9 +152,6 @@ Camera::Camera()
height = 512;
resolution = 1;
- motion.pre = transform_identity();
- motion.post = transform_identity();
- use_motion = false;
use_perspective_motion = false;
shutter_curve.resize(RAMP_TABLE_SIZE);
@@ -317,15 +315,22 @@ void Camera::update(Scene *scene)
kcam->ndctoworld = ndctoworld;
/* camera motion */
- kcam->have_motion = 0;
+ kcam->num_motion_steps = 0;
kcam->have_perspective_motion = 0;
+ kernel_camera_motion.clear();
+
+ /* Test if any of the transforms are actually different. */
+ bool have_motion = false;
+ for(size_t i = 0; i < motion.size(); i++) {
+ have_motion = have_motion || motion[i] != matrix;
+ }
if(need_motion == Scene::MOTION_PASS) {
/* TODO(sergey): Support perspective (zoom, fov) motion. */
if(type == CAMERA_PANORAMA) {
- if(use_motion) {
- kcam->motion_pass_pre = transform_inverse(motion.pre);
- kcam->motion_pass_post = transform_inverse(motion.post);
+ if(have_motion) {
+ kcam->motion_pass_pre = transform_inverse(motion[0]);
+ kcam->motion_pass_post = transform_inverse(motion[motion.size()-1]);
}
else {
kcam->motion_pass_pre = kcam->worldtocamera;
@@ -333,9 +338,9 @@ void Camera::update(Scene *scene)
}
}
else {
- if(use_motion) {
- kcam->perspective_pre = cameratoraster * transform_inverse(motion.pre);
- kcam->perspective_post = cameratoraster * transform_inverse(motion.post);
+ if(have_motion) {
+ kcam->perspective_pre = cameratoraster * transform_inverse(motion[0]);
+ kcam->perspective_post = cameratoraster * transform_inverse(motion[motion.size()-1]);
}
else {
kcam->perspective_pre = worldtoraster;
@@ -344,9 +349,10 @@ void Camera::update(Scene *scene)
}
}
else if(need_motion == Scene::MOTION_BLUR) {
- if(use_motion) {
- transform_motion_decompose(&kcam->motion, &motion, &matrix);
- kcam->have_motion = 1;
+ if(have_motion) {
+ kernel_camera_motion.resize(motion.size());
+ transform_motion_decompose(kernel_camera_motion.data(), motion.data(), motion.size());
+ kcam->num_motion_steps = motion.size();
}
/* TODO(sergey): Support other types of camera. */
@@ -469,6 +475,16 @@ void Camera::device_update(Device * /* device */,
}
dscene->data.cam = kernel_camera;
+
+ size_t num_motion_steps = kernel_camera_motion.size();
+ if(num_motion_steps) {
+ DecomposedTransform *camera_motion = dscene->camera_motion.alloc(num_motion_steps);
+ memcpy(camera_motion, kernel_camera_motion.data(), sizeof(*camera_motion) * num_motion_steps);
+ dscene->camera_motion.copy_to_device();
+ }
+ else {
+ dscene->camera_motion.free();
+ }
}
void Camera::device_update_volume(Device * /*device*/,
@@ -495,10 +511,11 @@ void Camera::device_update_volume(Device * /*device*/,
}
void Camera::device_free(Device * /*device*/,
- DeviceScene * /*dscene*/,
+ DeviceScene *dscene,
Scene *scene)
{
scene->lookup_tables->remove_table(&shutter_table_offset);
+ dscene->camera_motion.free();
}
bool Camera::modified(const Camera& cam)
@@ -509,7 +526,6 @@ bool Camera::modified(const Camera& cam)
bool Camera::motion_modified(const Camera& cam)
{
return !((motion == cam.motion) &&
- (use_motion == cam.use_motion) &&
(use_perspective_motion == cam.use_perspective_motion));
}
@@ -706,17 +722,17 @@ float Camera::world_to_raster_size(float3 P)
* may be a better way to do this, but calculating differentials from the
* point directly ahead seems to produce good enough results. */
#if 0
- float2 dir = direction_to_panorama(&kernel_camera, normalize(D));
+ float2 dir = direction_to_panorama(&kernel_camera, kernel_camera_motion.data(), normalize(D));
float3 raster = transform_perspective(&cameratoraster, make_float3(dir.x, dir.y, 0.0f));
ray.t = 1.0f;
- camera_sample_panorama(&kernel_camera, raster.x, raster.y, 0.0f, 0.0f, &ray);
+ camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), raster.x, raster.y, 0.0f, 0.0f, &ray);
if(ray.t == 0.0f) {
/* No differentials, just use from directly ahead. */
- camera_sample_panorama(&kernel_camera, 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
+ camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
}
#else
- camera_sample_panorama(&kernel_camera, 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
+ camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
#endif
differential_transfer(&ray.dP, ray.dP, ray.D, ray.dD, ray.D, dist);
@@ -728,4 +744,27 @@ float Camera::world_to_raster_size(float3 P)
return res;
}
+bool Camera::use_motion() const
+{
+ return motion.size() > 1;
+}
+
+float Camera::motion_time(int step) const
+{
+ return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
+}
+
+int Camera::motion_step(float time) const
+{
+ if(use_motion()) {
+ for(int step = 0; step < motion.size(); step++) {
+ if(time == motion_time(step)) {
+ return step;
+ }
+ }
+ }
+
+ return -1;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 8f49a372f24..37d05c01bd9 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -141,8 +141,8 @@ public:
Transform matrix;
/* motion */
- MotionTransform motion;
- bool use_motion, use_perspective_motion;
+ array<Transform> motion;
+ bool use_perspective_motion;
float fov_pre, fov_post;
/* computed camera parameters */
@@ -176,6 +176,7 @@ public:
/* Kernel camera data, copied here for dicing. */
KernelCamera kernel_camera;
+ array<DecomposedTransform> kernel_camera_motion;
/* functions */
Camera();
@@ -199,6 +200,11 @@ public:
/* Calculates the width of a pixel at point in world space. */
float world_to_raster_size(float3 P);
+ /* Motion blur. */
+ float motion_time(int step) const;
+ int motion_step(float time) const;
+ bool use_motion() const;
+
private:
/* Private utility functions. */
float3 transform_raster_to_world(float raster_x, float raster_y);
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 6201775b992..bde340ae928 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -139,9 +139,10 @@ void Object::compute_bounds(bool motion_blur)
if(mtfm.post == transform_empty()) {
mtfm.post = tfm;
}
+ mtfm.mid = tfm;
DecomposedMotionTransform decomp;
- transform_motion_decompose(&decomp, &mtfm, &tfm);
+ transform_motion_decompose(&decomp.pre, &mtfm.pre, 3);
bounds = BoundBox::empty;
@@ -151,7 +152,7 @@ void Object::compute_bounds(bool motion_blur)
for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
- transform_motion_interpolate(&ttfm, &decomp, t);
+ transform_motion_array_interpolate(&ttfm, &decomp.pre, 3, t);
bounds.grow(mbounds.transformed(&ttfm));
}
}
@@ -422,8 +423,10 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
if(ob->use_motion) {
/* decompose transformations for interpolation. */
DecomposedMotionTransform decomp;
+ MotionTransform mtfm = ob->motion;
+ mtfm.mid = tfm;
- transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
+ transform_motion_decompose(&decomp.pre, &mtfm.pre, 3);
kobject.tfm = decomp;
flag |= SD_OBJECT_MOTION;
state->have_motion = true;
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index e9b9b417e30..6fc6e453aff 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -62,6 +62,7 @@ DeviceScene::DeviceScene(Device *device)
objects(device, "__objects", MEM_TEXTURE),
object_motion_pass(device, "__object_motion_pass", MEM_TEXTURE),
object_flag(device, "__object_flag", MEM_TEXTURE),
+ camera_motion(device, "__camera_motion", MEM_TEXTURE),
attributes_map(device, "__attributes_map", MEM_TEXTURE),
attributes_float(device, "__attributes_float", MEM_TEXTURE),
attributes_float3(device, "__attributes_float3", MEM_TEXTURE),
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index aebd84f92d8..74e1df2f1d2 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -90,6 +90,9 @@ public:
device_vector<Transform> object_motion_pass;
device_vector<uint> object_flag;
+ /* cameras */
+ device_vector<DecomposedTransform> camera_motion;
+
/* attributes */
device_vector<uint4> attributes_map;
device_vector<float> attributes_float;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index e8d9558c38d..5732faf2a36 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -656,7 +656,7 @@ DeviceRequestedFeatures Session::get_requested_device_features()
*/
requested_features.use_hair = false;
requested_features.use_object_motion = false;
- requested_features.use_camera_motion = scene->camera->use_motion;
+ requested_features.use_camera_motion = scene->camera->use_motion();
foreach(Object *object, scene->objects) {
Mesh *mesh = object->mesh;
if(mesh->num_curves()) {