mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
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
This commit is contained in:
parent
fc479bcdaf
commit
5952dfe73f
2 changed files with 28 additions and 5 deletions
|
@ -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 = 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.
|
_input->render(1, 1); // Preallocate the RT on the driver and GPU.
|
||||||
_output = _input->get_texture();
|
_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) {
|
if (data) {
|
||||||
|
@ -231,8 +245,7 @@ void upscaling_instance::video_render(gs_effect_t* effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROFILING
|
#ifdef ENABLE_PROFILING
|
||||||
::streamfx::obs::gs::debug_marker profiler0{::streamfx::obs::gs::debug_color_source,
|
::streamfx::obs::gs::debug_marker profiler0{::streamfx::obs::gs::debug_color_source, "StreamFX Upscaling"};
|
||||||
"StreamFX Video Super-Resolution"};
|
|
||||||
::streamfx::obs::gs::debug_marker profiler0_0{::streamfx::obs::gs::debug_color_gray, "'%s' on '%s'",
|
::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)};
|
obs_source_get_name(_self), obs_source_get_name(parent)};
|
||||||
#endif
|
#endif
|
||||||
|
@ -310,8 +323,13 @@ void upscaling_instance::video_render(gs_effect_t* effect)
|
||||||
#ifdef ENABLE_PROFILING
|
#ifdef ENABLE_PROFILING
|
||||||
::streamfx::obs::gs::debug_marker profiler1{::streamfx::obs::gs::debug_color_render, "Render"};
|
::streamfx::obs::gs::debug_marker profiler1{::streamfx::obs::gs::debug_color_render, "Render"};
|
||||||
#endif
|
#endif
|
||||||
gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), _output->get_object());
|
if (_standard_effect->has_parameter("Channel0", ::streamfx::obs::gs::effect_parameter::type::Texture)) {
|
||||||
while (gs_effect_loop(effect, "Draw")) {
|
_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);
|
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!
|
// 3. In any other case, register the filter!
|
||||||
_info.id = S_PREFIX "filter-upscaling";
|
_info.id = S_PREFIX "filter-upscaling";
|
||||||
_info.type = OBS_SOURCE_TYPE_FILTER;
|
_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);
|
set_resolution_enabled(true);
|
||||||
finish_setup();
|
finish_setup();
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "obs/gs/gs-effect.hpp"
|
||||||
#include "obs/gs/gs-rendertarget.hpp"
|
#include "obs/gs/gs-rendertarget.hpp"
|
||||||
#include "obs/gs/gs-texture.hpp"
|
#include "obs/gs/gs-texture.hpp"
|
||||||
#include "obs/obs-source-factory.hpp"
|
#include "obs/obs-source-factory.hpp"
|
||||||
|
@ -53,6 +54,10 @@ namespace streamfx::filter::upscaling {
|
||||||
std::mutex _provider_lock;
|
std::mutex _provider_lock;
|
||||||
std::shared_ptr<util::threadpool::task> _provider_task;
|
std::shared_ptr<util::threadpool::task> _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::rendertarget> _input;
|
||||||
std::shared_ptr<::streamfx::obs::gs::texture> _output;
|
std::shared_ptr<::streamfx::obs::gs::texture> _output;
|
||||||
bool _dirty;
|
bool _dirty;
|
||||||
|
|
Loading…
Reference in a new issue