mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-13 07:15:06 +00:00
filter-sdf-effects: Support for scaling SDF Texture Size
This allows increasing or decreasing the accuracy of the Signed Distance Field at runtime without requiring the initial source to be resized. Use case for this would be small text where the higher quality would only be noticable on the shadow and not the text itself.
This commit is contained in:
parent
493ef5da23
commit
75009c617a
3 changed files with 58 additions and 19 deletions
|
@ -138,6 +138,8 @@ Filter.SDFEffects.Shadow.Outer.Offset.X="Outer Offset X"
|
||||||
Filter.SDFEffects.Shadow.Outer.Offset.Y="Outer Offset Y"
|
Filter.SDFEffects.Shadow.Outer.Offset.Y="Outer Offset Y"
|
||||||
Filter.SDFEffects.Shadow.Outer.Color="Outer Color"
|
Filter.SDFEffects.Shadow.Outer.Color="Outer Color"
|
||||||
Filter.SDFEffects.Shadow.Outer.Alpha="Outer Alpha"
|
Filter.SDFEffects.Shadow.Outer.Alpha="Outer Alpha"
|
||||||
|
Filter.SDFEffects.SDF.Scale="SDF Texture Scale"
|
||||||
|
Filter.SDFEffects.SDF.Scale.Description="Percentage to scale the SDF Texture Size by, relative to the Source Size.\nA higher value results in better quality, but slower updates,\n while lower values result in faster updates, but lower quality."
|
||||||
|
|
||||||
# Filter - Shape
|
# Filter - Shape
|
||||||
Filter.Shape="Shape"
|
Filter.Shape="Shape"
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#define P_SHADOW_OUTER_COLOR "Filter.SDFEffects.Shadow.Outer.Color"
|
#define P_SHADOW_OUTER_COLOR "Filter.SDFEffects.Shadow.Outer.Color"
|
||||||
#define P_SHADOW_OUTER_ALPHA "Filter.SDFEffects.Shadow.Outer.Alpha"
|
#define P_SHADOW_OUTER_ALPHA "Filter.SDFEffects.Shadow.Outer.Alpha"
|
||||||
|
|
||||||
|
#define P_SDF_SCALE "Filter.SDFEffects.SDF.Scale"
|
||||||
|
|
||||||
// Initializer & Finalizer
|
// Initializer & Finalizer
|
||||||
INITIALIZER(filterShadowFactoryInitializer)
|
INITIALIZER(filterShadowFactoryInitializer)
|
||||||
{
|
{
|
||||||
|
@ -137,21 +139,24 @@ void filter::sdf_effects::sdf_effects_factory::destroy(void* inptr)
|
||||||
|
|
||||||
void filter::sdf_effects::sdf_effects_factory::get_defaults(obs_data_t* data)
|
void filter::sdf_effects::sdf_effects_factory::get_defaults(obs_data_t* data)
|
||||||
{
|
{
|
||||||
obs_data_set_bool(data, P_SHADOW_INNER, false);
|
obs_data_set_default_bool(data, P_SHADOW_INNER, false);
|
||||||
obs_data_set_double(data, P_SHADOW_INNER_RANGE_MINIMUM, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_INNER_RANGE_MINIMUM, 0.0);
|
||||||
obs_data_set_double(data, P_SHADOW_INNER_RANGE_MAXIMUM, 4.0);
|
obs_data_set_default_double(data, P_SHADOW_INNER_RANGE_MAXIMUM, 4.0);
|
||||||
obs_data_set_double(data, P_SHADOW_INNER_OFFSET_X, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_INNER_OFFSET_X, 0.0);
|
||||||
obs_data_set_double(data, P_SHADOW_INNER_OFFSET_Y, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_INNER_OFFSET_Y, 0.0);
|
||||||
obs_data_set_int(data, P_SHADOW_INNER_COLOR, 0x00000000);
|
obs_data_set_default_int(data, P_SHADOW_INNER_COLOR, 0x00000000);
|
||||||
obs_data_set_double(data, P_SHADOW_INNER_ALPHA, 100.0);
|
obs_data_set_default_double(data, P_SHADOW_INNER_ALPHA, 100.0);
|
||||||
|
|
||||||
obs_data_set_bool(data, P_SHADOW_OUTER, false);
|
obs_data_set_default_bool(data, P_SHADOW_OUTER, false);
|
||||||
obs_data_set_double(data, P_SHADOW_OUTER_RANGE_MINIMUM, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_OUTER_RANGE_MINIMUM, 0.0);
|
||||||
obs_data_set_double(data, P_SHADOW_OUTER_RANGE_MAXIMUM, 4.0);
|
obs_data_set_default_double(data, P_SHADOW_OUTER_RANGE_MAXIMUM, 4.0);
|
||||||
obs_data_set_double(data, P_SHADOW_OUTER_OFFSET_X, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_OUTER_OFFSET_X, 0.0);
|
||||||
obs_data_set_double(data, P_SHADOW_OUTER_OFFSET_Y, 0.0);
|
obs_data_set_default_double(data, P_SHADOW_OUTER_OFFSET_Y, 0.0);
|
||||||
obs_data_set_int(data, P_SHADOW_OUTER_COLOR, 0x00000000);
|
obs_data_set_default_int(data, P_SHADOW_OUTER_COLOR, 0x00000000);
|
||||||
obs_data_set_double(data, P_SHADOW_OUTER_ALPHA, 100.0);
|
obs_data_set_default_double(data, P_SHADOW_OUTER_ALPHA, 100.0);
|
||||||
|
|
||||||
|
obs_data_set_default_bool(data, S_ADVANCED, false);
|
||||||
|
obs_data_set_default_double(data, P_SDF_SCALE, 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* filter::sdf_effects::sdf_effects_factory::get_properties(void* inptr)
|
obs_properties_t* filter::sdf_effects::sdf_effects_factory::get_properties(void* inptr)
|
||||||
|
@ -235,8 +240,16 @@ bool filter::sdf_effects::sdf_effects_instance::cb_modified_outside(void*, obs_p
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool filter::sdf_effects::sdf_effects_instance::cb_modified_advanced(void* ptr, obs_properties_t* props,
|
||||||
|
obs_property* prop, obs_data_t* settings)
|
||||||
|
{
|
||||||
|
bool show_advanced = obs_data_get_bool(settings, S_ADVANCED);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_SDF_SCALE), show_advanced);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
filter::sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, obs_source_t* self)
|
filter::sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, obs_source_t* self)
|
||||||
: m_self(self), m_source_rendered(false)
|
: m_self(self), m_source_rendered(false), m_sdf_scale(1.0)
|
||||||
{
|
{
|
||||||
this->m_source_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
this->m_source_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
this->m_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
this->m_sdf_write = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
||||||
|
@ -311,6 +324,13 @@ obs_properties_t* filter::sdf_effects::sdf_effects_instance::get_properties()
|
||||||
0.1);
|
0.1);
|
||||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SHADOW_OUTER_ALPHA)));
|
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SHADOW_OUTER_ALPHA)));
|
||||||
|
|
||||||
|
p = obs_properties_add_bool(props, S_ADVANCED, P_TRANSLATE(S_ADVANCED));
|
||||||
|
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(S_ADVANCED)));
|
||||||
|
obs_property_set_modified_callback2(p, cb_modified_advanced, this);
|
||||||
|
|
||||||
|
p = obs_properties_add_float_slider(props, P_SDF_SCALE, P_TRANSLATE(P_SDF_SCALE), 0.1, 500.0, 0.1);
|
||||||
|
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SDF_SCALE)));
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +351,8 @@ void filter::sdf_effects::sdf_effects_instance::update(obs_data_t* data)
|
||||||
this->m_outer_offset_y = float_t(obs_data_get_double(data, P_SHADOW_OUTER_OFFSET_Y));
|
this->m_outer_offset_y = float_t(obs_data_get_double(data, P_SHADOW_OUTER_OFFSET_Y));
|
||||||
this->m_outer_color = (obs_data_get_int(data, P_SHADOW_OUTER_COLOR) & 0x00FFFFFF)
|
this->m_outer_color = (obs_data_get_int(data, P_SHADOW_OUTER_COLOR) & 0x00FFFFFF)
|
||||||
| (int32_t(obs_data_get_double(data, P_SHADOW_OUTER_ALPHA) * 2.55) << 24);
|
| (int32_t(obs_data_get_double(data, P_SHADOW_OUTER_ALPHA) * 2.55) << 24);
|
||||||
|
|
||||||
|
this->m_sdf_scale = double_t(obs_data_get_double(data, P_SDF_SCALE) / 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t filter::sdf_effects::sdf_effects_instance::get_width()
|
uint32_t filter::sdf_effects::sdf_effects_instance::get_width()
|
||||||
|
@ -413,18 +435,29 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t*)
|
||||||
throw std::runtime_error("SDF Effect no loaded");
|
throw std::runtime_error("SDF Effect no loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scale SDF Size
|
||||||
|
double_t sdfW, sdfH;
|
||||||
|
sdfW = baseW * m_sdf_scale;
|
||||||
|
sdfH = baseH * m_sdf_scale;
|
||||||
|
if (sdfW <= 1) {
|
||||||
|
sdfW = 1.0;
|
||||||
|
}
|
||||||
|
if (sdfH <= 1) {
|
||||||
|
sdfH = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto op = m_sdf_write->render(baseW, baseH);
|
auto op = m_sdf_write->render(sdfW, sdfH);
|
||||||
gs_ortho(0, (float)baseW, 0, (float)baseH, -1, 1);
|
gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1);
|
||||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
|
||||||
|
|
||||||
sdf_effect->get_parameter("_image").set_texture(this->m_source_texture);
|
sdf_effect->get_parameter("_image").set_texture(this->m_source_texture);
|
||||||
sdf_effect->get_parameter("_size").set_float2(float_t(baseW), float_t(baseH));
|
sdf_effect->get_parameter("_size").set_float2(float_t(sdfW), float_t(sdfH));
|
||||||
sdf_effect->get_parameter("_sdf").set_texture(this->m_sdf_texture);
|
sdf_effect->get_parameter("_sdf").set_texture(this->m_sdf_texture);
|
||||||
sdf_effect->get_parameter("_threshold").set_float(0.5);
|
sdf_effect->get_parameter("_threshold").set_float(0.5);
|
||||||
|
|
||||||
while (gs_effect_loop(sdf_effect->get_object(), "Draw")) {
|
while (gs_effect_loop(sdf_effect->get_object(), "Draw")) {
|
||||||
gs_draw_sprite(this->m_sdf_texture->get_object(), 0, baseW, baseH);
|
gs_draw_sprite(this->m_sdf_texture->get_object(), 0, sdfW, sdfH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->m_sdf_write.swap(this->m_sdf_read);
|
this->m_sdf_write.swap(this->m_sdf_read);
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace filter {
|
||||||
// Distance Field
|
// Distance Field
|
||||||
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read;
|
std::shared_ptr<gs::rendertarget> m_sdf_write, m_sdf_read;
|
||||||
std::shared_ptr<gs::texture> m_sdf_texture;
|
std::shared_ptr<gs::texture> m_sdf_texture;
|
||||||
|
double_t m_sdf_scale;
|
||||||
|
|
||||||
bool m_inner_shadow;
|
bool m_inner_shadow;
|
||||||
float_t m_inner_range_min;
|
float_t m_inner_range_min;
|
||||||
|
@ -115,6 +116,9 @@ namespace filter {
|
||||||
static bool cb_modified_outside(void* ptr, obs_properties_t* props, obs_property* prop,
|
static bool cb_modified_outside(void* ptr, obs_properties_t* props, obs_property* prop,
|
||||||
obs_data_t* settings);
|
obs_data_t* settings);
|
||||||
|
|
||||||
|
static bool cb_modified_advanced(void* ptr, obs_properties_t* props, obs_property* prop,
|
||||||
|
obs_data_t* settings);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sdf_effects_instance(obs_data_t* settings, obs_source_t* self);
|
sdf_effects_instance(obs_data_t* settings, obs_source_t* self);
|
||||||
~sdf_effects_instance();
|
~sdf_effects_instance();
|
||||||
|
|
Loading…
Reference in a new issue