Commit: ade35bac9355679f0966249b7d65992ef024eb04
Author: Sergey Sharybin
Date:   Fri Nov 20 14:42:34 2015 +0500
Branches: master
https://developer.blender.org/rBade35bac9355679f0966249b7d65992ef024eb04

Cycles: Implement rolling shutter effect

This is an attempt to emulate real CMOS cameras which reads sensor by scanlines
and hence different scanlines are sampled at a different moment in time, which
causes so called rolling shutter effect. This effect will, for example, make
vertical straight lines being curved when doing horizontal camera pan.

This is controlled by the Shutter Type option in the Motion Blur panel.

Additionally, since scanline sampling is not instantaneous it's possible to have
motion blur on top of rolling shutter.

This is controlled by the Rolling Shutter Time slider which controls balance
between pure rolling shutter effect and pure motion blur effect.

Reviewers: brecht, juicyfruit, dingto, keir

Differential Revision: https://developer.blender.org/D1624

===================================================================

M       intern/cycles/blender/addon/properties.py
M       intern/cycles/blender/addon/ui.py
M       intern/cycles/blender/blender_camera.cpp
M       intern/cycles/kernel/kernel_camera.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/camera.cpp
M       intern/cycles/render/camera.h

===================================================================

diff --git a/intern/cycles/blender/addon/properties.py 
b/intern/cycles/blender/addon/properties.py
index cbd1a8b..f48bc93 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -531,6 +531,24 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
                 ),
             )
 
+        cls.rolling_shutter_type = EnumProperty(
+            name="Shutter Type",
+            default='NONE',
+            description="Type of rolling shutter effect matching CMOS-based 
cameras",
+            items=(
+                ('NONE', "None", "No rolling shutter effect used"),
+                ('TOP', "Top-Bottom", "Sensor is being scanned from top to 
bottom")
+                # TODO(seergey): Are there real cameras with different 
scanning direction?
+                ),
+            )
+
+        cls.rolling_shutter_duration = FloatProperty(
+            name="Rolling Shutter Duration",
+            description="Scanline \"exposure\" time for the rolling shutter 
effect",
+            default = 0.1,
+            min=0.0, max=1.0,
+            )
+
     @classmethod
     def unregister(cls):
         del bpy.types.Scene.cycles
diff --git a/intern/cycles/blender/addon/ui.py 
b/intern/cycles/blender/addon/ui.py
index e2aa266..495b2f2 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -281,6 +281,12 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, 
Panel):
         row.operator("render.shutter_curve_preset", icon='LINCURVE', 
text="").shape = 'LINE'
         row.operator("render.shutter_curve_preset", icon='NOCURVE', 
text="").shape = 'MAX'
 
+        col = layout.column()
+        col.prop(cscene, "rolling_shutter_type")
+        row = col.row()
+        row.active = cscene.rolling_shutter_type != 'NONE'
+        row.prop(cscene, "rolling_shutter_duration")
+
 
 class CyclesRender_PT_film(CyclesButtonsPanel, Panel):
     bl_label = "Film"
diff --git a/intern/cycles/blender/blender_camera.cpp 
b/intern/cycles/blender/blender_camera.cpp
index cde3840..5f2e076 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -39,6 +39,9 @@ struct BlenderCamera {
        Camera::MotionPosition motion_position;
        float shutter_curve[RAMP_TABLE_SIZE];
 
+       Camera::RollingShutterType rolling_shutter_type;
+       float rolling_shutter_duration;
+
        float aperturesize;
        uint apertureblades;
        float aperturerotation;
@@ -86,6 +89,8 @@ static void blender_camera_init(BlenderCamera *bcam, 
BL::RenderSettings b_render
        bcam->sensor_fit = BlenderCamera::AUTO;
        bcam->shuttertime = 1.0f;
        bcam->motion_position = Camera::MOTION_POSITION_CENTER;
+       bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE;
+       bcam->rolling_shutter_duration = 0.1f;
        bcam->border.right = 1.0f;
        bcam->border.top = 1.0f;
        bcam->pano_viewplane.right = 1.0f;
@@ -418,6 +423,9 @@ static void blender_camera_sync(Camera *cam, BlenderCamera 
*bcam, int width, int
        cam->fov_post = cam->fov;
        cam->motion_position = bcam->motion_position;
 
+       cam->rolling_shutter_type = bcam->rolling_shutter_type;
+       cam->rolling_shutter_duration = bcam->rolling_shutter_duration;
+
        memcpy(cam->shutter_curve, bcam->shutter_curve, 
sizeof(cam->shutter_curve));
 
        /* border */
@@ -460,6 +468,19 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, 
BL::Object b_override
                        break;
        }
 
+       switch(RNA_enum_get(&cscene, "rolling_shutter_type")) {
+               case 0:
+                       bcam.rolling_shutter_type = 
Camera::ROLLING_SHUTTER_NONE;
+                       break;
+               case 1:
+                       bcam.rolling_shutter_type = Camera::ROLLING_SHUTTER_TOP;
+                       break;
+               default:
+                       bcam.rolling_shutter_type = 
Camera::ROLLING_SHUTTER_NONE;
+                       break;
+       }
+       bcam.rolling_shutter_duration = RNA_float_get(&cscene, 
"rolling_shutter_duration");
+
        /* border */
        if(b_render.use_border()) {
                bcam.border.left = b_render.border_min_x();
diff --git a/intern/cycles/kernel/kernel_camera.h 
b/intern/cycles/kernel/kernel_camera.h
index 01017ea..c51174b 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -294,8 +294,37 @@ ccl_device void camera_sample(KernelGlobals *kg, int x, 
int y, float filter_u, f
                ray->time = TIME_INVALID;
        }
        else {
+               /* TODO(sergey): Such lookup is unneeded when there's rolling 
shutter
+                * effect in use but rollign shutter duration is set to 0.0.
+                */
                const int shutter_table_offset = 
kernel_data.cam.shutter_table_offset;
                ray->time = lookup_table_read(kg, time, shutter_table_offset, 
SHUTTER_TABLE_SIZE);
+               /* TODO(sergey): Currently single rolling shutter effect type 
only
+                * where scanlines are acquired from top to bottom and whole 
scanline
+                * is acquired at once (no delay in acquisition happens between 
pixels
+                * of sinle scanline).
+                *
+                * Might want to support more models in the future.
+                */
+               if(kernel_data.cam.rolling_shutter_type) {
+                       /* Time corresponding to a fully rolling shutter only 
effect:
+                        * top of the frame is time 0.0, bottom of the frame is 
time 1.0.
+                        */
+                       const float time = 1.0f - (float)y / 
kernel_data.cam.height;
+                       const float duration = 
kernel_data.cam.rolling_shutter_duration;
+                       if(duration != 0.0f) {
+                               /* This isn't fully physical correct, but lets 
us to have simple
+                                * controls in the interface. The idea here is 
basically sort of
+                                * linear interpolation between how much 
rolling shutter effect
+                                * exist on the frame and how much of it is a 
motion blur effect.
+                                */
+                               ray->time = (ray->time - 0.5f) * duration;
+                               ray->time += (time - 0.5f) * (1.0f - duration) 
+ 0.5f;
+                       }
+                       else {
+                               ray->time = time;
+                       }
+               }
        }
 #endif
 
diff --git a/intern/cycles/kernel/kernel_types.h 
b/intern/cycles/kernel/kernel_types.h
index 04d013c..8682325 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -849,6 +849,11 @@ typedef struct KernelCamera {
        PerspectiveMotionTransform perspective_motion;
 
        int shutter_table_offset;
+
+       /* Rolling shutter */
+       int rolling_shutter_type;
+       float rolling_shutter_duration;
+
        int pad;
 } KernelCamera;
 
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 33a5c00..9c17a11 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -109,6 +109,10 @@ Camera::Camera()
        for(int i = 0; i < num_shutter_points; ++i) {
                shutter_curve[i] = 1.0f;
        }
+
+       /* Initialize rolling shutter effect. */
+       rolling_shutter_type = ROLLING_SHUTTER_NONE;
+       rolling_shutter_duration = 0.1f;
 }
 
 Camera::~Camera()
@@ -357,6 +361,10 @@ void Camera::device_update(Device *device, DeviceScene 
*dscene, Scene *scene)
        /* Camera in volume. */
        kcam->is_inside_volume = 0;
 
+       /* Rolling shutter effect */
+       kcam->rolling_shutter_type = rolling_shutter_type;
+       kcam->rolling_shutter_duration = rolling_shutter_duration;
+
        previous_need_motion = need_motion;
 }
 
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 1c26afa..d4a66b6 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -47,12 +47,28 @@ public:
                MOTION_POSITION_END,
        };
 
+       /* Specifies rolling shutter effect. */
+       enum RollingShutterType {
+               /* No rolling shutter effect. */
+               ROLLING_SHUTTER_NONE = 0,
+               /* Sensor is being scanned vertically from top to bottom. */
+               ROLLING_SHUTTER_TOP,
+       };
+
        /* motion blur */
        float shuttertime;
        MotionPosition motion_position;
        float shutter_curve[RAMP_TABLE_SIZE];
        size_t shutter_table_offset;
 
+       /* ** Rolling shutter effect. ** */
+       /* Defines rolling shutter effect type. */
+       RollingShutterType rolling_shutter_type;
+       /* Specifies exposure time of scanlines when using
+        * rolling shutter effect.
+        */
+       float rolling_shutter_duration;
+
        /* depth of field */
        float focaldistance;
        float aperturesize;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to