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:
-rw-r--r--intern/cycles/blender/addon/properties.py18
-rw-r--r--intern/cycles/blender/addon/ui.py6
-rw-r--r--intern/cycles/blender/blender_camera.cpp21
-rw-r--r--intern/cycles/kernel/kernel_camera.h29
-rw-r--r--intern/cycles/kernel/kernel_types.h5
-rw-r--r--intern/cycles/render/camera.cpp8
-rw-r--r--intern/cycles/render/camera.h16
7 files changed, 103 insertions, 0 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index cbd1a8b1922..f48bc93cabf 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 e2aa266d53b..495b2f21f7b 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 cde3840b796..5f2e0762964 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 01017eabde2..c51174b645d 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 04d013ceb9c..8682325998d 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 33a5c004033..9c17a11e0f1 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 1c26afafeff..d4a66b66072 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;