VSE: default to new "Auto" image filter for strips
Part of "improve filtering situation" (#116980), now strip scaling filter defaults to "Auto" which has logic like: - No scale, no rotation, integer positions: Nearest (fastest) - Scaling up by more than 2x: Cubic Mitchell, so you get nicer blending between pixels than with bilinear, - Scaling down by more than 2x: Box, so that many pixels are averaged properly without too much aliasing, - Otherwise: Bilinear Existing strips that use Bilinear (which is default) get switched to Auto when loading older files. All of this has an advantage that unless you have some special needs for your look, you can leave it at default and it will look decently good at either large up-scaling or large down-scaling, but not waste performance if you don't use any scaling at all. Previously none of the choices were good in "all cases": box (née subsampled3x3) only looks good when scaling down, cubic only looks good when scaling up, default bilinear leaves performance on the table when you don't use any scale/rotation, etc. On something like Gold movie current edit, most of the strips effectively use Nearest now, except some that are translated into non-integer pixel positions; those stay effectively Bilinear. Pull Request: https://projects.blender.org/blender/blender/pulls/117853
This commit is contained in:
committed by
Aras Pranckevicius
parent
2c385a03f6
commit
e1f8775807
@@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 17
|
||||
#define BLENDER_FILE_SUBVERSION 18
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_movieclip_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "DNA_defaults.h"
|
||||
@@ -61,6 +62,7 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_tracking.h"
|
||||
|
||||
#include "SEQ_iterator.hh"
|
||||
#include "SEQ_retiming.hh"
|
||||
#include "SEQ_sequencer.hh"
|
||||
|
||||
@@ -1936,6 +1938,15 @@ static void fix_geometry_nodes_object_info_scale(bNodeTree &ntree)
|
||||
}
|
||||
}
|
||||
|
||||
static bool seq_filter_bilinear_to_auto(Sequence *seq, void * /*user_data*/)
|
||||
{
|
||||
StripTransform *transform = seq->strip->transform;
|
||||
if (transform != nullptr && transform->filter == SEQ_TRANSFORM_FILTER_BILINEAR) {
|
||||
transform->filter = SEQ_TRANSFORM_FILTER_AUTO;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) {
|
||||
@@ -2848,6 +2859,14 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 18)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
if (scene->ed != nullptr) {
|
||||
SEQ_for_each_callback(&scene->ed->seqbase, seq_filter_bilinear_to_auto, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -836,6 +836,7 @@ typedef enum SequenceColorTag {
|
||||
|
||||
/* Sequence->StripTransform->filter */
|
||||
enum {
|
||||
SEQ_TRANSFORM_FILTER_AUTO = -1,
|
||||
SEQ_TRANSFORM_FILTER_NEAREST = 0,
|
||||
SEQ_TRANSFORM_FILTER_BILINEAR = 1,
|
||||
SEQ_TRANSFORM_FILTER_BOX = 2,
|
||||
|
||||
@@ -1696,6 +1696,11 @@ static void rna_def_strip_crop(BlenderRNA *brna)
|
||||
}
|
||||
|
||||
static const EnumPropertyItem transform_filter_items[] = {
|
||||
{SEQ_TRANSFORM_FILTER_AUTO,
|
||||
"AUTO",
|
||||
0,
|
||||
"Auto",
|
||||
"Automatically choose filter based on scaling factor"},
|
||||
{SEQ_TRANSFORM_FILTER_NEAREST, "NEAREST", 0, "Nearest", "Use nearest sample"},
|
||||
{SEQ_TRANSFORM_FILTER_BILINEAR,
|
||||
"BILINEAR",
|
||||
@@ -1770,7 +1775,7 @@ static void rna_def_strip_transform(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "filter", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "filter");
|
||||
RNA_def_property_enum_items(prop, transform_filter_items);
|
||||
RNA_def_property_enum_default(prop, SEQ_TRANSFORM_FILTER_BILINEAR);
|
||||
RNA_def_property_enum_default(prop, SEQ_TRANSFORM_FILTER_AUTO);
|
||||
RNA_def_property_ui_text(prop, "Filter", "Type of filter to use for image transformation");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
|
||||
|
||||
|
||||
@@ -500,6 +500,30 @@ static bool seq_image_transform_transparency_gained(const SeqRenderData *context
|
||||
seq_image_quad[3]);
|
||||
}
|
||||
|
||||
/* Automatic filter:
|
||||
* - No scale, no rotation and non-fractional position: nearest.
|
||||
* - Scale up by more than 2x: cubic mitchell.
|
||||
* - Scale down by more than 2x: box.
|
||||
* - Otherwise: bilinear. */
|
||||
static eIMBInterpolationFilterMode get_auto_filter(const StripTransform *transform)
|
||||
{
|
||||
const float sx = fabsf(transform->scale_x);
|
||||
const float sy = fabsf(transform->scale_y);
|
||||
if (sx > 2.0f && sy > 2.0f) {
|
||||
return IMB_FILTER_CUBIC_MITCHELL;
|
||||
}
|
||||
if (sx < 0.5f && sy < 0.5f) {
|
||||
return IMB_FILTER_BOX;
|
||||
}
|
||||
const float px = transform->xofs;
|
||||
const float py = transform->yofs;
|
||||
const float rot = transform->rotation;
|
||||
if (sx == 1.0f && sy == 1.0f && roundf(px) == px && roundf(py) == py && rot == 0.0f) {
|
||||
return IMB_FILTER_NEAREST;
|
||||
}
|
||||
return IMB_FILTER_BILINEAR;
|
||||
}
|
||||
|
||||
static void sequencer_preprocess_transform_crop(
|
||||
ImBuf *in, ImBuf *out, const SeqRenderData *context, Sequence *seq, const bool is_proxy_image)
|
||||
{
|
||||
@@ -524,6 +548,9 @@ static void sequencer_preprocess_transform_crop(
|
||||
const StripTransform *transform = seq->strip->transform;
|
||||
eIMBInterpolationFilterMode filter = IMB_FILTER_NEAREST;
|
||||
switch (transform->filter) {
|
||||
case SEQ_TRANSFORM_FILTER_AUTO:
|
||||
filter = get_auto_filter(seq->strip->transform);
|
||||
break;
|
||||
case SEQ_TRANSFORM_FILTER_NEAREST:
|
||||
filter = IMB_FILTER_NEAREST;
|
||||
break;
|
||||
|
||||
@@ -77,7 +77,7 @@ static Strip *seq_strip_alloc(int type)
|
||||
strip->transform->scale_y = 1;
|
||||
strip->transform->origin[0] = 0.5f;
|
||||
strip->transform->origin[1] = 0.5f;
|
||||
strip->transform->filter = SEQ_TRANSFORM_FILTER_BILINEAR;
|
||||
strip->transform->filter = SEQ_TRANSFORM_FILTER_AUTO;
|
||||
strip->crop = static_cast<StripCrop *>(MEM_callocN(sizeof(StripCrop), "StripCrop"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user