diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 3700da3263e..3678391ccd5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -268,6 +268,19 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): col.prop(cscene, "motion_blur_position", text="Position") col.prop(rd, "motion_blur_shutter") + col = layout.column() + col.label("Shutter curve:") + col.template_curve_mapping(rd, "motion_blur_shutter_curve") + + col = layout.column(align=True) + row = col.row(align=True) + row.operator("render.shutter_curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH' + row.operator("render.shutter_curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND' + row.operator("render.shutter_curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT' + row.operator("render.shutter_curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP' + row.operator("render.shutter_curve_preset", icon='LINCURVE', text="").shape = 'LINE' + row.operator("render.shutter_curve_preset", icon='NOCURVE', text="").shape = 'MAX' + 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 7cb5e38d4e5..cde3840b796 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -37,6 +37,7 @@ struct BlenderCamera { float lens; float shuttertime; Camera::MotionPosition motion_position; + float shutter_curve[RAMP_TABLE_SIZE]; float aperturesize; uint apertureblades; @@ -417,6 +418,8 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->fov_post = cam->fov; cam->motion_position = bcam->motion_position; + memcpy(cam->shutter_curve, bcam->shutter_curve, sizeof(cam->shutter_curve)); + /* border */ cam->border = bcam->border; cam->viewport_camera_border = bcam->viewport_camera_border; @@ -437,6 +440,9 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override bcam.pixelaspect.x = b_render.pixel_aspect_x(); bcam.pixelaspect.y = b_render.pixel_aspect_y(); bcam.shuttertime = b_render.motion_blur_shutter(); + curvemapping_to_array(b_render.motion_blur_shutter_curve(), + bcam.shutter_curve, + RAMP_TABLE_SIZE); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); switch(RNA_enum_get(&cscene, "motion_blur_position")) { @@ -545,6 +551,9 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine b_eng bcam->farclip = b_v3d.clip_end(); bcam->lens = b_v3d.lens(); bcam->shuttertime = b_scene.render().motion_blur_shutter(); + curvemapping_to_array(b_scene.render().motion_blur_shutter_curve(), + bcam->shutter_curve, + RAMP_TABLE_SIZE); if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { /* camera view */ diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index bd1c37a7560..2e9e9266404 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -62,6 +62,16 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size } } +static inline void curvemapping_to_array(BL::CurveMapping cumap, float *data, int size) +{ + cumap.update(); + BL::CurveMap curve = cumap.curves[0]; + for(int i = 0; i < size; i++) { + float t = (float)i/(float)(size-1); + data[i] = curve.evaluate(t); + } +} + static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve) { cumap.update(); diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index b88972b74e1..e5d348031e9 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -54,7 +54,7 @@ void curvemapping_set_black_white(struct CurveMapping *cumap, con enum { CURVEMAP_SLOPE_NEGATIVE = 0, CURVEMAP_SLOPE_POSITIVE = 1, - CURVEMAP_SLOPE_RAISE_FALL = 2, + CURVEMAP_SLOPE_POS_NEG = 2, }; void curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index c6e3d1919e1..3fb9ff1c9e8 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -368,7 +368,7 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) MEM_freeN(cuma->curve); cuma->curve = newpoints; } - else if (slope == CURVEMAP_SLOPE_RAISE_FALL) { + else if (slope == CURVEMAP_SLOPE_POS_NEG) { const int num_points = cuma->totpoint * 2 - 1; CurveMapPoint *new_points = MEM_mallocN(num_points * sizeof(CurveMapPoint), "curve symmetric points"); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d73797ccbd1..bb61ecd63cb 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -351,6 +351,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) scen->preview = BKE_previewimg_copy(sce->preview); } + curvemapping_copy_data(&scen->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve); + return scen; } @@ -462,6 +464,7 @@ void BKE_scene_free(Scene *sce) BKE_color_managed_view_settings_free(&sce->view_settings); BKE_previewimg_free(&sce->preview); + curvemapping_free_data(&sce->r.mblur_shutter_curve); } void BKE_scene_init(Scene *sce) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b112f3d43d6..d6ba79f5a98 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6007,6 +6007,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) } sce->preview = direct_link_preview_image(fd, sce->preview); + + direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve); } /* ************ READ WM ***************** */ diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 16635851032..72f9897730a 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -53,6 +53,7 @@ #include "DNA_genfile.h" +#include "BKE_colortools.h" #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_node.h" @@ -909,4 +910,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } + + { + if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "CurveMapping", "mblur_shutter_curve")) { + Scene *scene; + for (scene = main->scene.first; scene != NULL; scene = scene->id.next) { + CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve; + curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f); + curvemapping_initialize(curve_mapping); + curvemap_reset(curve_mapping->cm, + &curve_mapping->clipr, + CURVE_PRESET_MAX, + CURVEMAP_SLOPE_POS_NEG); + } + } + } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 4449db14c50..bc94ef9cc19 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2576,6 +2576,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) } write_previews(wd, sce->preview); + write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); sce= sce->id.next; } diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 26f313cb3fe..fb07b03c286 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -89,6 +89,7 @@ void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot); /* render_internal.c */ void RENDER_OT_render(struct wmOperatorType *ot); +void RENDER_OT_shutter_curve_preset(struct wmOperatorType *ot); void render_view3d_update(struct RenderEngine *engine, const struct bContext *C); void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 57aafb549ac..f44374b1d7b 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1640,3 +1640,45 @@ Scene *ED_render_job_get_current_scene(const bContext *C) } return NULL; } + +/* Motion blur curve preset */ + +static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + CurveMapping *mblur_shutter_curve = &scene->r.mblur_shutter_curve; + CurveMap *cm = mblur_shutter_curve->cm; + int preset = RNA_enum_get(op->ptr, "shape"); + + cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + mblur_shutter_curve->preset = preset; + curvemap_reset(cm, + &mblur_shutter_curve->clipr, + mblur_shutter_curve->preset, + CURVEMAP_SLOPE_POS_NEG); + curvemapping_changed(mblur_shutter_curve, false); + + return OPERATOR_FINISHED; +} + +void RENDER_OT_shutter_curve_preset(wmOperatorType *ot) +{ + PropertyRNA *prop; + static EnumPropertyItem prop_shape_items[] = { + {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""}, + {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""}, + {CURVE_PRESET_MAX, "MAX", 0, "Max", ""}, + {CURVE_PRESET_LINE, "LINE", 0, "Line", ""}, + {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""}, + {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""}, + {0, NULL, 0, NULL, NULL}}; + + ot->name = "Shutter Curve Preset"; + ot->description = "Set shutter curve"; + ot->idname = "RENDER_OT_shutter_curve_preset"; + + ot->exec = render_shutter_curve_preset_exec; + + prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", ""); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ +} diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index f98083f7e74..c09e8576dc2 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -93,6 +93,7 @@ void ED_operatortypes_render(void) WM_operatortype_append(RENDER_OT_view_show); WM_operatortype_append(RENDER_OT_render); WM_operatortype_append(RENDER_OT_view_cancel); + WM_operatortype_append(RENDER_OT_shutter_curve_preset); /* render_opengl.c */ WM_operatortype_append(RENDER_OT_opengl); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 89f5e6499bf..26b1d7bd645 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -702,6 +702,9 @@ typedef struct RenderData { short actview; short views_format; short pad8[2]; + + /* Motion blur shutter */ + struct CurveMapping mblur_shutter_curve; } RenderData; /* *************************************************************** */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 403b59f1371..1149214e533 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5366,6 +5366,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); + + prop = RNA_def_property(srna, "motion_blur_shutter_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "mblur_shutter_curve"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Shutter Curve", "Curve defining the shutter's openness over time"); /* border */ prop = RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index eb0b331f866..17e5751c38b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -59,6 +59,7 @@ #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" @@ -505,6 +506,8 @@ void RE_FreeRender(Render *re) BLI_freelistN(&re->r.layers); BLI_freelistN(&re->r.views); + curvemapping_free_data(&re->r.mblur_shutter_curve); + /* main dbase can already be invalid now, some database-free code checks it */ re->main = NULL; re->scene = NULL; @@ -666,6 +669,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->r = *rd; BLI_duplicatelist(&re->r.layers, &rd->layers); BLI_duplicatelist(&re->r.views, &rd->views); + curvemapping_copy_data(&re->r.mblur_shutter_curve, &rd->mblur_shutter_curve); if (source) { /* reuse border flags from source renderer */