diff --git a/properties/scene.py b/properties/scene.py index 6b30461b..25811716 100644 --- a/properties/scene.py +++ b/properties/scene.py @@ -44,8 +44,13 @@ def update_stamp(self, context): self.render_stamp += self.render_stamp_patterns def update_name(self, context): - mapping = {'render_stamp_post_processing_stage': "Render Stamp", + mapping = {'bloom_post_processing_stage': "Bloom", + 'chromatic_aberration_post_processing_stage': "Chromatic Aberration", 'color_map_post_processing_stage': "Color Map", + 'render_stamp_post_processing_stage': "Render Stamp", + 'tone_map_post_processing_stage': "Tone Map", + 'vignette_post_processing_stage': "Vignette", + # FIXME there's no other reference of this.. should it still be here? 'isolines_post_processing_stage': "Isolines"} self.name = mapping[self.model] @@ -54,59 +59,74 @@ def update_name(self, context): model: bpy.props.EnumProperty(name="model", items=[ + ('bloom_post_processing_stage', + "Bloom", ""), + ('chromatic_aberration_post_processing_stage', + "Chromatic Aberration", ""), + ('color_map_post_processing_stage', + "Color Map", ""), ('render_stamp_post_processing_stage', "Render Stamp", ""), - ('color_map_post_processing_stage', "Color Map", "")], + ('tone_map_post_processing_stage', + "Tone Map", ""), + ('vignette_post_processing_stage', + "Vignette", "")], default='render_stamp_post_processing_stage', update=update_name) - # Render stamp - render_stamp: bpy.props.StringProperty(name="render_stamp", - description="Render stamp text", - default="appleseed {lib-version} | Time: {render-time}") + # Bloom + iterations: bpy.props.IntProperty(name="iterations", + default=4, + min=1, + soft_max=5) - render_stamp_patterns: bpy.props.EnumProperty(name="render_stamp_patterns", - description="Variables to insert into the render stamp", - items=[ - ('{lib-version}', - "Library Version", ""), - ('{lib-name}', - "Library Name", ""), - ('{lib-variant}', - "Library Variant", ""), - ('{lib-config}', - "Library Configuration", ""), - ('{lib-build-date}', - "Library Build Date", ""), - ('{lib-build-time}', - "Library Build Time", ""), - ('{render-time}', - "Render Time", ""), - ('{peak-memory}', "Peak Memory", "")], - default="{render-time}", - update=update_stamp) + intensity: bpy.props.FloatProperty(name="intensity", + default=0.1, + min=0.0, + soft_max=1.0) - # Color map + threshold: bpy.props.FloatProperty(name="threshold", + default=1.0, + min=0.0, + soft_max=10.0) + + soft_knee: bpy.props.FloatProperty(name="soft_knee", + default=0.5, + min=0.0, + soft_max=1.0) + + debug_blur: bpy.props.BoolProperty(name="debug_blur", + default=False) + + # Chromatic Aberration + strength: bpy.props.FloatProperty(name="line_thickness", + default=0.4, + min=0.0, + max=1.0) + + fringe_smoothness: bpy.props.IntProperty(name="fringe_smoothness", + default=6, + min=1, + soft_max=20) + + # Color Map color_map: bpy.props.EnumProperty(name="color_map", items=[('inferno', "Inferno", ""), ('jet', "Jet", ""), ('magma', "Magma", ""), ('plasma', "Plasma", ""), ('viridis', "Viridis", ""), + ('turbo', "Turbo", ""), ('custom', "Custom", "")], default='inferno') + color_map_file_path: bpy.props.StringProperty(name="color_map_file_path", + default="", + subtype='FILE_PATH') + auto_range: bpy.props.BoolProperty(name="auto_range", default=True) - add_legend_bar: bpy.props.BoolProperty(name="add_legend_bar", - default=True) - - legend_bar_ticks: bpy.props.IntProperty(name="legend_bar_ticks", - default=8, - min=2, - soft_max=64) - range_min: bpy.props.FloatProperty(name="range_min", default=0.0, soft_min=0.0, @@ -117,9 +137,13 @@ def update_name(self, context): soft_min=0.0, soft_max=1.0) - color_map_file_path: bpy.props.StringProperty(name="color_map_file_path", - default="", - subtype='FILE_PATH') + add_legend_bar: bpy.props.BoolProperty(name="add_legend_bar", + default=True) + + legend_bar_ticks: bpy.props.IntProperty(name="legend_bar_ticks", + default=8, + min=2, + soft_max=64) render_isolines: bpy.props.BoolProperty(name="render_isolines", default=False) @@ -128,6 +152,156 @@ def update_name(self, context): default=1.0, min=0.5, soft_max=5.0) + # Render Stamp + render_stamp: bpy.props.StringProperty(name="render_stamp", # TODO rename to `format_string` (?) + description="Render stamp text", + default="appleseed {lib-version} | Time: {render-time}") + + render_stamp_patterns: bpy.props.EnumProperty(name="render_stamp_patterns", + description="Variables to insert into the render stamp", + items=[ + ('{lib-name}', + "Library Name", ""), + ('{lib-version}', + "Library Version", ""), + ('{lib-variant}', # NOTE this could probably be deleted as it was updated to + "Library Variant", ""), # `{lib-cpu-features}` (see projectfileupdater.cpp#L1962). + ('{lib-cpu-features}', + "Library CPU Features", ""), + ('{lib-config}', + "Library Configuration", ""), + ('{lib-build-date}', + "Library Build Date", ""), + ('{lib-build-time}', + "Library Build Time", ""), + ('{render-time}', + "Render Time", ""), + ('{peak-memory}', + "Peak Memory", "")], + default="{render-time}", + update=update_stamp) + + scale_factor: bpy.props.FloatProperty(name="scale_factor", + default=1.0, + min=0.1, + max=20.0) + + # Tone Map + tone_map_operator: bpy.props.EnumProperty(name="tone_map_operator", + description="Operator that defines the tone mapping curve.", + items=[ + ('linear', + "Linear", ""), + ('aces_narkowicz', + "ACES (Narkowicz)", ""), + ('aces_unreal', + "ACES (Unreal)", ""), + ('filmic_hejl', + "Filmic (Hejl)", ""), + ('filmic_piecewise', + "Filmic (Piecewise)", ""), + ('filmic_uncharted', + "Filmic (Uncharted)", ""), + ('reinhard', + "Reinhard", ""), + ('reinhard_extended', + "Reinhard (Extended)", "")], + default='linear') + + clamp_colors: bpy.props.BoolProperty(name="clamp_colors", + default=True) + + aces_narkowicz_exposure_bias: bpy.props.FloatProperty(name="aces_narkowicz_exposure_bias", + default=0.8, + min=0.0, + max=10.0) + + filmic_uncharted_A: bpy.props.FloatProperty(name="filmic_uncharted_A", + default=0.22, + min=0.0, + max=1.0) + + filmic_uncharted_B: bpy.props.FloatProperty(name="filmic_uncharted_B", + default=0.30, + min=0.0, + max=1.0) + + filmic_uncharted_C: bpy.props.FloatProperty(name="filmic_uncharted_C", + default=0.10, + min=0.0, + max=1.0) + + filmic_uncharted_D: bpy.props.FloatProperty(name="filmic_uncharted_D", + default=0.20, + min=0.0, + max=1.0) + + filmic_uncharted_E: bpy.props.FloatProperty(name="filmic_uncharted_E", + default=0.01, + min=0.0, + max=1.0) + + filmic_uncharted_F: bpy.props.FloatProperty(name="filmic_uncharted_F", + default=0.30, + min=0.0, + max=1.0) + + filmic_uncharted_W: bpy.props.FloatProperty(name="filmic_uncharted_W", + default=1.2, + min=0.0, + max=1.0) + + filmic_uncharted_exposure_bias: bpy.props.FloatProperty(name="filmic_uncharted_exposure_bias", + default=2.0, + min=0.0, + max=10.0) + + filmic_piecewise_toe_strength: bpy.props.FloatProperty(name="filmic_piecewise_toe_strength", + default=0.0, + soft_min=0.0, + soft_max=1.0) + + filmic_piecewise_toe_length: bpy.props.FloatProperty(name="filmic_piecewise_toe_length", + default=0.5, + soft_min=0.0, + soft_max=1.0) + + filmic_piecewise_shoulder_strength: bpy.props.FloatProperty(name="filmic_piecewise_shoulder_strength", + default=0.0, + soft_min=0.0, + soft_max=1.0) + + filmic_piecewise_shoulder_length: bpy.props.FloatProperty(name="filmic_piecewise_shoulder_length", + default=0.5, + min=0.0001, + soft_max=32.0) + + filmic_piecewise_shoulder_angle: bpy.props.FloatProperty(name="filmic_piecewise_shoulder_angle", + default=0.0, + soft_min=0.0, + soft_max=1.0) + + reinhard_use_luminance: bpy.props.BoolProperty(name="reinhard_use_luminance", + default=True) + + reinhard_extended_max_white: bpy.props.FloatProperty(name="reinhard_extended_max_white", + default=1.0, + min=0.0, + soft_max=10000.0) + + reinhard_extended_use_luminance: bpy.props.BoolProperty(name="reinhard_extended_use_luminance", + default=True) + + # Vignette + intensity: bpy.props.FloatProperty(name="intensity", + default=0.5, + min=0.0, + max=1.0) + + anisotropy: bpy.props.FloatProperty(name="anisotropy", + default=0.0, + min=0.0, + max=1.0) class AppleseedTextureConvertProps(bpy.types.PropertyGroup): diff --git a/translators/scene.py b/translators/scene.py index 0792cb42..fe369e95 100644 --- a/translators/scene.py +++ b/translators/scene.py @@ -692,7 +692,7 @@ def __calc_crop_window(self, depsgraph, context=None): elif depsgraph.scene_eval.render.use_border and context.region_data.view_perspective == 'CAMERA': """ I can't explain how the following code produces the correct render window. - I basically threw every parameter combination I could think of together + I basically threw every parameter combination I could think of together until the result looked right. """ @@ -780,25 +780,77 @@ def __set_aovs(self, depsgraph): return aovs + def __get_post_processing_stage_params(self, stage, order): + params = {'order': order} + + if stage.model == 'bloom_post_processing_stage': + params.update({'iterations': stage.iterations, + 'intensity': stage.intensity, + 'threshold': stage.threshold, + 'soft_knee': stage.soft_knee, + 'debug_blur': stage.debug_blur}) + + elif stage.model == 'chromatic_aberration_post_processing_stage': + params.update({'strength': stage.strength, + 'fringe_smoothness': stage.fringe_smoothness}) + + elif stage.model == 'color_map_post_processing_stage': + params.update({'color_map': stage.color_map, + 'auto_range': stage.auto_range, + 'range_min': stage.range_min, + 'range_max': stage.range_max, + 'add_legend_bar': stage.add_legend_bar, + 'legend_bar_ticks': stage.legend_bar_ticks, + 'render_isolines': stage.render_isolines, + 'line_thickness': stage.line_thickness}) + + if stage.color_map == 'custom': + params.update({'color_map_file_path': stage.color_map_file_path}) + + elif stage.model == 'render_stamp_post_processing_stage': + params.update({'format_string': stage.render_stamp, # FIXME shouldn't this be `stage.format_string`? + 'scale_factor': stage.scale_factor}) + + elif stage.model == 'tone_map_post_processing_stage': + params.update({'tone_map_operator': stage.tone_map_operator, + 'clamp_colors': stage.clamp_colors}) + + # Add tone map operator-specific parameters. + operator_params = {'linear': {}, + 'aces_narkowicz': {'aces_narkowicz_exposure_bias': stage.aces_narkowicz_exposure_bias}, + 'aces_unreal': {}, + 'filmic_hejl': {}, + 'filmic_piecewise': {'filmic_piecewise_toe_strength': stage.filmic_piecewise_toe_strength, + 'filmic_piecewise_toe_length': stage.filmic_piecewise_toe_length, + 'filmic_piecewise_shoulder_strength': stage.filmic_piecewise_shoulder_strength, + 'filmic_piecewise_shoulder_length': stage.filmic_piecewise_shoulder_length, + 'filmic_piecewise_shoulder_angle': stage.filmic_piecewise_shoulder_angle}, + 'filmic_uncharted': {'filmic_uncharted_A': stage.filmic_uncharted_A, + 'filmic_uncharted_B': stage.filmic_uncharted_B, + 'filmic_uncharted_C': stage.filmic_uncharted_C, + 'filmic_uncharted_D': stage.filmic_uncharted_D, + 'filmic_uncharted_E': stage.filmic_uncharted_E, + 'filmic_uncharted_F': stage.filmic_uncharted_F, + 'filmic_uncharted_W': stage.filmic_uncharted_W, + 'filmic_uncharted_exposure_bias': stage.filmic_uncharted_exposure_bias}, + 'reinhard': {'reinhard_use_luminance': stage.reinhard_use_luminance}, + 'reinhard_extended': {'reinhard_extended_max_white': stage.reinhard_extended_max_white, + 'reinhard_extended_use_luminance': stage.reinhard_extended_use_luminance}} + + params.update(operator_params[stage.tone_map_operator]) + + else: + assert stage.model == 'vignette_post_processing_stage', stage.model + params.update({'intensity': stage.intensity, + 'anisotropy': stage.anisotropy}) + + return params + def __set_post_process(self, depsgraph): asr_scene_props = depsgraph.scene_eval.appleseed for index, stage in enumerate(asr_scene_props.post_processing_stages): - if stage.model == 'render_stamp_post_processing_stage': - params = {'order': index, 'format_string': stage.render_stamp} - else: - params = {'order': index, - 'color_map': stage.color_map, - 'auto_range': stage.auto_range, - 'range_min': stage.range_min, - 'range_max': stage.range_max, - 'add_legend_bar': stage.add_legend_bar, - 'legend_bar_ticks': stage.legend_bar_ticks, - 'render_isolines': stage.render_isolines, - 'line_thickness': stage.line_thickness} - - if stage.color_map == 'custom': - params['color_map_file_path'] = stage.color_map_file_path + params = self.__get_post_processing_stage_params(stage, index) post_process = asr.PostProcessingStage(stage.model, stage.name, params) diff --git a/ui/render.py b/ui/render.py index 82aa6ba3..6bba8451 100644 --- a/ui/render.py +++ b/ui/render.py @@ -443,10 +443,14 @@ def draw(self, context): if pp_stages: current_stage = pp_stages[asr_scene_props.post_processing_stages_index] layout.prop(current_stage, "model", text="Model") - if current_stage.model == 'render_stamp_post_processing_stage': - layout.prop(current_stage, "render_stamp", text="Stamp") - layout.prop(current_stage, "render_stamp_patterns", text="Add Stamp") - else: + + if current_stage.model == 'bloom_post_processing_stage': + pass # TODO + + elif current_stage.model == 'chromatic_aberration_post_processing_stage': + pass # TODO + + elif current_stage.model == 'color_map_post_processing_stage': layout.prop(current_stage, "color_map", text="Mode") row = layout.row() row.enabled = current_stage.color_map == 'custom' @@ -473,6 +477,17 @@ def draw(self, context): row.enabled = current_stage.render_isolines row.prop(current_stage, "line_thickness", text="Line Thickness") + elif current_stage.model == 'render_stamp_post_processing_stage': + layout.prop(current_stage, "render_stamp", text="Stamp") # TODO sync with properties/scene.py + layout.prop(current_stage, "render_stamp_patterns", text="Add Stamp") + + elif current_stage.model == 'tone_map_post_processing_stage': + pass # TODO + + else: + assert current_stage.model == 'vignette_post_processing_stage', current_stage.model + pass # TODO + class ASRENDER_PT_motion_blur(bpy.types.Panel, ASRENDER_PT_base): COMPAT_ENGINES = {'APPLESEED_RENDER'}