From 5952dfe73f242eefc9dccfc56a9efbf2dc308007 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Wed, 6 Oct 2021 02:15:28 +0200 Subject: [PATCH] filter/upscaling: Restore alpha after processing As none of the known Upscaling algorithms handle Alpha, we need to manually restore and interpolate it properly. While this technically reduces visual quality slightly, the chances of this being noticed are slim to none considering that Upscaling is already a questionable solution to quality. Linear was picked here as it produces the best overall result for scaling, keeping gradients mostly in one piece. Mostly. Fixes #646 --- source/filters/filter-upscaling.cpp | 28 +++++++++++++++++++++++----- source/filters/filter-upscaling.hpp | 5 +++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/source/filters/filter-upscaling.cpp b/source/filters/filter-upscaling.cpp index dbb6041..71202e4 100644 --- a/source/filters/filter-upscaling.cpp +++ b/source/filters/filter-upscaling.cpp @@ -102,6 +102,20 @@ upscaling_instance::upscaling_instance(obs_data_t* data, obs_source_t* self) _input = std::make_shared<::streamfx::obs::gs::rendertarget>(GS_RGBA_UNORM, GS_ZS_NONE); _input->render(1, 1); // Preallocate the RT on the driver and GPU. _output = _input->get_texture(); + + // Load the required effect. + _standard_effect = + std::make_shared<::streamfx::obs::gs::effect>(::streamfx::data_file_path("effects/standard.effect")); + + // Create Samplers + _channel0_sampler = std::make_shared<::streamfx::obs::gs::sampler>(); + _channel0_sampler->set_filter(gs_sample_filter::GS_FILTER_LINEAR); + _channel0_sampler->set_address_mode_u(GS_ADDRESS_CLAMP); + _channel0_sampler->set_address_mode_v(GS_ADDRESS_CLAMP); + _channel1_sampler = std::make_shared<::streamfx::obs::gs::sampler>(); + _channel1_sampler->set_filter(gs_sample_filter::GS_FILTER_LINEAR); + _channel1_sampler->set_address_mode_u(GS_ADDRESS_CLAMP); + _channel1_sampler->set_address_mode_v(GS_ADDRESS_CLAMP); } if (data) { @@ -231,8 +245,7 @@ void upscaling_instance::video_render(gs_effect_t* effect) } #ifdef ENABLE_PROFILING - ::streamfx::obs::gs::debug_marker profiler0{::streamfx::obs::gs::debug_color_source, - "StreamFX Video Super-Resolution"}; + ::streamfx::obs::gs::debug_marker profiler0{::streamfx::obs::gs::debug_color_source, "StreamFX Upscaling"}; ::streamfx::obs::gs::debug_marker profiler0_0{::streamfx::obs::gs::debug_color_gray, "'%s' on '%s'", obs_source_get_name(_self), obs_source_get_name(parent)}; #endif @@ -310,8 +323,13 @@ void upscaling_instance::video_render(gs_effect_t* effect) #ifdef ENABLE_PROFILING ::streamfx::obs::gs::debug_marker profiler1{::streamfx::obs::gs::debug_color_render, "Render"}; #endif - gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), _output->get_object()); - while (gs_effect_loop(effect, "Draw")) { + if (_standard_effect->has_parameter("Channel0", ::streamfx::obs::gs::effect_parameter::type::Texture)) { + _standard_effect->get_parameter("Channel0").set_texture(_output); + } + if (_standard_effect->has_parameter("Channel1", ::streamfx::obs::gs::effect_parameter::type::Texture)) { + _standard_effect->get_parameter("Channel1").set_texture(_input->get_texture()); + } + while (gs_effect_loop(_standard_effect->get_object(), "RestoreAlpha")) { gs_draw_sprite(nullptr, 0, _out_size.first, _out_size.second); } } @@ -509,7 +527,7 @@ upscaling_factory::upscaling_factory() // 3. In any other case, register the filter! _info.id = S_PREFIX "filter-upscaling"; _info.type = OBS_SOURCE_TYPE_FILTER; - _info.output_flags = OBS_SOURCE_VIDEO /*| OBS_SOURCE_SRGB*/; + _info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW /*| OBS_SOURCE_SRGB*/; set_resolution_enabled(true); finish_setup(); diff --git a/source/filters/filter-upscaling.hpp b/source/filters/filter-upscaling.hpp index 2614ee1..564016d 100644 --- a/source/filters/filter-upscaling.hpp +++ b/source/filters/filter-upscaling.hpp @@ -22,6 +22,7 @@ #include #include #include +#include "obs/gs/gs-effect.hpp" #include "obs/gs/gs-rendertarget.hpp" #include "obs/gs/gs-texture.hpp" #include "obs/obs-source-factory.hpp" @@ -53,6 +54,10 @@ namespace streamfx::filter::upscaling { std::mutex _provider_lock; std::shared_ptr _provider_task; + std::shared_ptr<::streamfx::obs::gs::effect> _standard_effect; + std::shared_ptr<::streamfx::obs::gs::sampler> _channel0_sampler; + std::shared_ptr<::streamfx::obs::gs::sampler> _channel1_sampler; + std::shared_ptr<::streamfx::obs::gs::rendertarget> _input; std::shared_ptr<::streamfx::obs::gs::texture> _output; bool _dirty;