diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 02c9ef5..fbd6dfa 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -38,6 +38,14 @@ Filter.Blur.Size="Size (Pixel)" Filter.Blur.Size.Description="Area size of the blur, large sizes may cause:\n- Skipped frames\n- Frame loss or drops\n- Input lag\n- GPU overheating\n- or other issues." Filter.Blur.Bilateral.Smoothing="Smoothing" Filter.Blur.Bilateral.Sharpness="Sharpness" +Filter.Blur.Directional="Directional Blur" +Filter.Blur.Directional.Description="Change the Blur into a Directional Blur. May not work with all Blur Types." +Filter.Blur.Directional.Angle="Angle" +Filter.Blur.Directional.Angle.Description="The angle in degrees for the Directional Blur." +Filter.Blur.StepScale="Step Scaling" +Filter.Blur.StepScale.Description="Scale the texel step used in the Blur shader, which allows for smaller Blur sizes to cover more space, at the cost of some quality.\nCan be combined with Directional Blur to change the behavior drastically." +Filter.Blur.StepScale.X="Step Scale X" +Filter.Blur.StepScale.Y="Step Scale Y" Filter.Blur.Region="Apply to Region only" Filter.Blur.Region.Description="Only apply the blur to a region inside the source." Filter.Blur.Region.Left="Left Edge" @@ -54,7 +62,6 @@ Filter.Blur.Region.Feather.Shift="Feather Shift" Filter.Blur.Region.Feather.Shift.Description="Shift of the Feather area, positive is inwards, negative is outwards." Filter.Blur.Region.Invert="Invert Region" Filter.Blur.Region.Invert.Description="Invert the region so that everything but this area is blurred." -Filter.Blur.ColorFormat="Color Format" Filter.Blur.Mask="Apply a Mask" Filter.Blur.Mask.Description="Apply a mask to the area that needs to be blurred, which allows for more control over the blurred area." Filter.Blur.Mask.Type="Mask Type" @@ -86,6 +93,7 @@ Filter.Blur.Mask.Alpha="Mask Alpha Filter" Filter.Blur.Mask.Alpha.Description="Filter the mask by this alpha value before applying it." Filter.Blur.Mask.Multiplier="Mask Multiplier" Filter.Blur.Mask.Multiplier.Description="Multiply the final mask value by this value." +Filter.Blur.ColorFormat="Color Format" # Filter - Custom Shader Filter.CustomShader="Custom Shader" diff --git a/source/filter-blur.cpp b/source/filter-blur.cpp index 5e0ef8b..07422b6 100644 --- a/source/filter-blur.cpp +++ b/source/filter-blur.cpp @@ -18,9 +18,9 @@ */ #include "filter-blur.h" +#include #include #include -#include #include "strings.h" #include "util-math.h" @@ -46,7 +46,11 @@ extern "C" { #define P_SIZE "Filter.Blur.Size" #define P_BILATERAL_SMOOTHING "Filter.Blur.Bilateral.Smoothing" #define P_BILATERAL_SHARPNESS "Filter.Blur.Bilateral.Sharpness" -#define P_COLORFORMAT "Filter.Blur.ColorFormat" +#define P_DIRECTIONAL "Filter.Blur.Directional" +#define P_DIRECTIONAL_ANGLE "Filter.Blur.Directional.Angle" +#define P_STEPSCALE "Filter.Blur.StepScale" +#define P_STEPSCALE_X "Filter.Blur.StepScale.X" +#define P_STEPSCALE_Y "Filter.Blur.StepScale.Y" #define P_MASK "Filter.Blur.Mask" #define P_MASK_TYPE "Filter.Blur.Mask.Type" #define P_MASK_TYPE_REGION "Filter.Blur.Mask.Type.Region" @@ -64,6 +68,7 @@ extern "C" { #define P_MASK_COLOR "Filter.Blur.Mask.Color" #define P_MASK_ALPHA "Filter.Blur.Mask.Alpha" #define P_MASK_MULTIPLIER "Filter.Blur.Mask.Multiplier" +#define P_COLORFORMAT "Filter.Blur.ColorFormat" // Initializer & Finalizer INITIALIZER(filterBlurFactoryInitializer) @@ -199,14 +204,13 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptrdirectional = obs_data_get_bool(settings, P_DIRECTIONAL); + this->angle = obs_data_get_double(settings, P_DIRECTIONAL_ANGLE); + + // Scaling + this->scaling = obs_data_get_bool(settings, P_STEPSCALE); + this->scale.first = obs_data_get_double(settings, P_STEPSCALE_X) / 100.0; + this->scale.second = obs_data_get_double(settings, P_STEPSCALE_Y) / 100.0; + // advanced if (obs_data_get_bool(settings, S_ADVANCED)) { color_format = obs_data_get_int(settings, P_COLORFORMAT); @@ -624,10 +658,55 @@ void filter::blur::blur_instance::video_render(gs_effect_t* effect) std::pair kvs[] = {{1.0f / baseW, 0.0f}, {0.0f, 1.0f / baseH}}; tex_intermediate = tex_source; // We need the original to work. + // Directional Blur + if (this->directional) { + // Directional Blur changes how + + kvs[0].first = (1.0f / baseW); + kvs[0].second = (1.0f / baseH); + kvs[1].first = kvs[0].first; + kvs[1].second = kvs[0].second; + + double_t rad = this->angle * PI / 180.0; + double_t c0 = cos(rad); + double_t s0 = sin(rad); + + kvs[0].first *= c0; + kvs[0].second *= s0; + + if (!this->scaling) { + kvs[1].first *= 0.0; + kvs[1].second *= 0.0; + } else { + kvs[1].first *= s0; + kvs[1].second *= c0; + } + } + + // Apply scaling + if (this->scaling) { + if (!this->directional) { + kvs[0].first *= float_t(this->scale.first); + kvs[0].second *= float_t(this->scale.second); + kvs[1].first *= float_t(this->scale.first); + kvs[1].second *= float_t(this->scale.second); + } else { + // Directional Blur changes how scaling works as it rotates and needs to be relative to the axis of rotation. + kvs[0].first *= float_t(this->scale.first); + kvs[0].second *= float_t(this->scale.first); + kvs[1].first *= float_t(this->scale.second); + kvs[1].second *= float_t(this->scale.second); + } + } + try { for (auto v : kvs) { float xpel = std::get<0>(v); float ypel = std::get<1>(v); + if ((abs(xpel) <= FLT_EPSILON) && (abs(ypel) <= FLT_EPSILON)) { + // Ignore passes that have a 0 texel modifier. + continue; + } { auto op = this->rt_primary->render(baseW, baseH); @@ -944,19 +1023,19 @@ void filter::blur::blur_factory::get_defaults(obs_data_t* data) obs_data_set_default_int(data, P_TYPE, filter::blur::type::Box); obs_data_set_default_int(data, P_SIZE, 5); - // bilateral Only + // Bilateral Only obs_data_set_default_double(data, P_BILATERAL_SMOOTHING, 50.0); obs_data_set_default_double(data, P_BILATERAL_SHARPNESS, 90.0); - // region + // Masking obs_data_set_default_bool(data, P_MASK, false); obs_data_set_default_int(data, P_MASK_TYPE, mask_type::Region); - obs_data_set_default_double(data, P_MASK_REGION_LEFT, 0.0f); - obs_data_set_default_double(data, P_MASK_REGION_RIGHT, 0.0f); - obs_data_set_default_double(data, P_MASK_REGION_TOP, 0.0f); - obs_data_set_default_double(data, P_MASK_REGION_BOTTOM, 0.0f); - obs_data_set_default_double(data, P_MASK_REGION_FEATHER, 0.0f); - obs_data_set_default_double(data, P_MASK_REGION_FEATHER_SHIFT, 0.0f); + obs_data_set_default_double(data, P_MASK_REGION_LEFT, 0.0); + obs_data_set_default_double(data, P_MASK_REGION_RIGHT, 0.0); + obs_data_set_default_double(data, P_MASK_REGION_TOP, 0.0); + obs_data_set_default_double(data, P_MASK_REGION_BOTTOM, 0.0); + obs_data_set_default_double(data, P_MASK_REGION_FEATHER, 0.0); + obs_data_set_default_double(data, P_MASK_REGION_FEATHER_SHIFT, 0.0); obs_data_set_default_bool(data, P_MASK_REGION_INVERT, false); char* default_file = obs_module_file("white.png"); obs_data_set_default_string(data, P_MASK_IMAGE, default_file); @@ -965,7 +1044,16 @@ void filter::blur::blur_factory::get_defaults(obs_data_t* data) obs_data_set_default_int(data, P_MASK_COLOR, 0xFFFFFFFFull); obs_data_set_default_double(data, P_MASK_MULTIPLIER, 1.0); - // advanced + // Directional Blur + obs_data_set_default_bool(data, P_DIRECTIONAL, false); + obs_data_set_default_double(data, P_DIRECTIONAL_ANGLE, 0.0); + + // Scaling + obs_data_set_default_bool(data, P_STEPSCALE, false); + obs_data_set_default_double(data, P_STEPSCALE_X, 100.0); + obs_data_set_default_double(data, P_STEPSCALE_Y, 100.0); + + // Advanced obs_data_set_default_bool(data, S_ADVANCED, false); obs_data_set_default_int(data, P_COLORFORMAT, ColorFormat::RGB); } diff --git a/source/filter-blur.h b/source/filter-blur.h index f755c51..a8da7ce 100644 --- a/source/filter-blur.h +++ b/source/filter-blur.h @@ -106,6 +106,14 @@ namespace filter { float_t multiplier; } mask; + // Directional + bool directional; + double_t angle; + + // Scale + bool scaling; + std::pair scale; + // advanced uint64_t color_format;