Files
test/source/blender/sequencer/SEQ_modifier.hh
Aras Pranckevicius 8a74f7c0b0 VSE: Execute modifiers in strip-local space (#145688)
Currently when a strip has a transform that does not fill the whole
render area, first the image of the strip is transformed, and then
any modifiers are applied on that. This is mostly in the new
Compositor modifier, where procedural textures, gradients, image
coordinates "stick to the screen" instead of following the transformed
strip.

This changes the behavior so that first the modifiers are applied
to the strip image, and then the strip is transformed. This is
potentially a visually breaking change:
- This can alter visual look of existing strip, especially if they are
  scaled. Previous behavior was first scale filtering, then modifier;
  now it is first modifier, then scale filtering.
- Most obvious change is Compositor modifier (which is new in 5.0).
- Compositor modifier can actually expand the input image (e.g. Blur
  node with "expand bounds" option set), and that works.
- Note that Masks continue to be applied in global/screen space. There
  can be small look differences with rotated/scaled strips that use
  masks, due to Mask application now needing to do filtered mask image
  lookups.
- If anyone needs previous behavior (modifier is applied on the
  "whole screen"), they can put transformed strip into a meta strip,
  and apply the modifier on the meta strip itself.

Compositor modifier examples with images in the PR.

Pull Request: https://projects.blender.org/blender/blender/pulls/146181
2025-10-07 13:51:41 +02:00

105 lines
3.2 KiB
C++

/* SPDX-FileCopyrightText: 2004 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup sequencer
*/
#include "BLI_function_ref.hh"
#include "DNA_sequence_types.h"
struct ARegionType;
struct BlendDataReader;
struct BlendWriter;
struct ImBuf;
struct ListBase;
struct Strip;
struct StripModifierData;
struct ID;
namespace blender::seq {
struct SeqRenderState;
struct StripScreenQuad;
struct RenderData;
struct StripModifierTypeInfo {
/**
* A unique identifier for this modifier. Used to generate the panel id type name.
* See #seq::modifier_type_panel_id.
*/
char idname[/*MAX_NAME*/ 64];
/* default name for the modifier */
char name[/*MAX_NAME*/ 64];
/* DNA structure name used on load/save filed */
char struct_name[/*MAX_NAME*/ 64];
/* size of modifier data structure, used by allocation */
int struct_size;
/* data initialization */
void (*init_data)(StripModifierData *smd);
/* free data used by modifier,
* only modifier-specific data should be freed, modifier descriptor would
* be freed outside of this callback
*/
void (*free_data)(StripModifierData *smd);
/* copy data from one modifier to another */
void (*copy_data)(StripModifierData *smd, StripModifierData *target);
/* Apply modifier on an image buffer. */
void (*apply)(const RenderData *render_data,
const Strip *strip,
const float transform[3][3],
StripModifierData *smd,
ImBuf *ibuf,
ImBuf *mask);
/** Register the panel types for the modifier's UI. */
void (*panel_register)(ARegionType *region_type);
/* Callback to read custom strip modifier data. */
void (*blend_write)(BlendWriter *writer, const StripModifierData *smd);
/* Callback to write custom strip modifier data. */
void (*blend_read)(BlendDataReader *reader, StripModifierData *smd);
};
void modifiers_init();
const StripModifierTypeInfo *modifier_type_info_get(int type);
StripModifierData *modifier_new(Strip *strip, const char *name, int type);
bool modifier_remove(Strip *strip, StripModifierData *smd);
void modifier_clear(Strip *strip);
void modifier_free(StripModifierData *smd);
void modifier_unique_name(Strip *strip, StripModifierData *smd);
StripModifierData *modifier_find_by_name(Strip *strip, const char *name);
StripModifierData *modifier_copy(Strip &strip_dst, StripModifierData *mod_src);
void modifier_list_copy(Strip *strip_new, Strip *strip);
int sequence_supports_modifiers(Strip *strip);
void modifier_blend_write(BlendWriter *writer, ListBase *modbase);
void modifier_blend_read_data(BlendDataReader *reader, ListBase *lb);
void modifier_persistent_uid_init(const Strip &strip, StripModifierData &smd);
bool modifier_move_to_index(Strip *strip, StripModifierData *smd, int new_index);
StripModifierData *modifier_get_active(const Strip *strip);
void modifier_set_active(Strip *strip, StripModifierData *smd);
static constexpr char STRIP_MODIFIER_TYPE_PANEL_PREFIX[] = "STRIPMOD_PT_";
void modifier_type_panel_id(eStripModifierType type, char *r_idname);
/* Iterate over all the modifiers and call the callback function for every referenced ID. */
void foreach_strip_modifier_id(Strip *strip, const FunctionRef<void(ID *)> fn);
} // namespace blender::seq