Cycles: Expose user-defined shutter curve to the interface
Shutter curve now can be controlled using curve mapping widget in the motion blur panel in Render buttons. Only mapping from 0..1 by x axis are allowed, Y values will be normalized to fill in 0..1 space as well automatically. Y values of 0 means fully closed shutter, Y values of 1 means fully opened shutter. Default mapping is set to old behavior when shutter opens and closes instantly. This shutter mapping curve could easily be used by any other render engine by accessing scene.render.motion_blur_shutter_curve. Reviewers: #cycles, brecht, juicyfruit, campbellbarton Differential Revision: https://developer.blender.org/D1585
This commit is contained in:
parent
6a529e14f4
commit
b909dfdae1
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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 ***************** */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 :/ */
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -702,6 +702,9 @@ typedef struct RenderData {
|
||||
short actview;
|
||||
short views_format;
|
||||
short pad8[2];
|
||||
|
||||
/* Motion blur shutter */
|
||||
struct CurveMapping mblur_shutter_curve;
|
||||
} RenderData;
|
||||
|
||||
/* *************************************************************** */
|
||||
|
@ -5367,6 +5367,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
|
||||
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);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user