0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-19 20:32:15 +02:00

obs-filters: Add NVIDIA Blur Filter & Background Blur

This adds a Background Blur filter which blurs the background for a
foreground speaker identified by NVIDIA AI Greenscreen FX.
Secondly, this adds a Blur filter based on NVIDIA Video Effects,
leveraging the Background Blur Filter where the mask used just sets the
whole frame as background.

Signed-off-by: pkv <pkv@obsproject.com>
This commit is contained in:
pkv 2023-08-26 21:40:09 +02:00 committed by Ryan Foster
parent 16f0bb68ae
commit f9bf7e6c00
5 changed files with 975 additions and 448 deletions

View File

@ -15,7 +15,7 @@ if(OS_WINDOWS)
if(ENABLE_NVVFX)
target_enable_feature(nv-filters "NVIDIA Video FX support" LIBNVVFX_ENABLED)
target_sources(nv-filters PRIVATE nvidia-greenscreen-filter.c)
target_sources(nv-filters PRIVATE nvidia-videofx-filter.c)
else()
target_disable_feature(nv-filters "NVIDIA Video FX support")
endif()

View File

@ -14,3 +14,6 @@ Nvvfx.Method.Greenscreen.Threshold="Threshold"
Nvvfx.OutdatedSDK="WARNING: Please upgrade both NVIDIA Video & Audio SDK. Your current version of Video SDK is outdated."
Nvvfx.Method.Greenscreen.Processing="Mask refresh frequency in frames"
Nvvfx.Method.Greenscreen.Processing.Hint="This alleviates GPU load by generating a mask every N frames only (2 on default)."
Nvvfx.Method.BlurFilter="NVIDIA Blur Filter"
Nvvfx.Method.BackgroundBlurFilter="NVIDIA Background Blur Filter"
Nvvfx.Method.Blur.Strength="Blur Intensity"

View File

@ -0,0 +1,158 @@
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;
uniform texture2d blurred;
sampler_state texSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VertInOut {
float2 uv : TEXCOORD0;
float4 pos : POSITION;
};
struct FragData {
float2 uv : TEXCOORD0;
};
struct FragPos {
float4 pos : POSITION;
};
VertInOut VSDefault(VertData v_in)
{
VertInOut v_out;
v_out.uv = v_in.uv;
v_out.pos = mul(float4(v_in.pos.xyz, 1.), ViewProj);
return v_out;
}
FragPos VSConvertUnorm(uint id : VERTEXID)
{
float idHigh = float(id >> 1);
float idLow = float(id & uint(1));
float x = idHigh * 4.0 - 1.0;
float y = idLow * 4.0 - 1.0;
FragPos vert_out;
vert_out.pos = float4(x, y, 0.0, 1.0);
return vert_out;
}
float4 Mask(FragData f_in)
{
float4 rgba = image.Sample(texSampler, f_in.uv);
rgba.rgb = max(float3(0.0, 0.0, 0.0), blurred.Sample(texSampler, f_in.uv).rgb / rgba.a);
return rgba;
}
float4 PSMask(FragData f_in) : TARGET
{
float4 rgba = Mask(f_in);
return rgba;
}
float4 PSMaskMultiply(FragData f_in) : TARGET
{
float4 rgba = Mask(f_in);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSMaskTonemap(FragData f_in) : TARGET
{
float4 rgba = Mask(f_in);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSMaskMultiplyTonemap(FragData f_in) : TARGET
{
float4 rgba = Mask(f_in);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDefault(FragPos f_in) : TARGET
{
float4 rgba = image.Load(int3(f_in.pos.xy, 0));
return rgba;
}
float4 PSConvertMultiply(FragPos f_in) : TARGET
{
float4 rgba = image.Load(int3(f_in.pos.xy, 0));
rgba.rgb *= multiplier;
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSMask(f_in);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSMaskMultiply(f_in);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSMaskTonemap(f_in);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSMaskMultiplyTonemap(f_in);
}
}
technique ConvertUnorm
{
pass
{
vertex_shader = VSConvertUnorm(id);
pixel_shader = PSDefault(f_in);
}
}
technique ConvertUnormMultiply
{
pass
{
vertex_shader = VSConvertUnorm(id);
pixel_shader = PSConvertMultiply(f_in);
}
}

View File

@ -14,6 +14,8 @@ extern void unload_nvidia_afx(void);
#endif
#ifdef LIBNVVFX_ENABLED
extern struct obs_source_info nvidia_greenscreen_filter_info;
extern struct obs_source_info nvidia_blur_filter_info;
extern struct obs_source_info nvidia_background_blur_filter_info;
extern bool load_nvidia_vfx(void);
extern void unload_nvidia_vfx(void);
#endif
@ -29,8 +31,11 @@ bool obs_module_load(void)
obs_enter_graphics();
const bool direct3d = gs_get_device_type() == GS_DEVICE_DIRECT3D_11;
obs_leave_graphics();
if (direct3d && load_nvidia_vfx())
if (direct3d && load_nvidia_vfx()) {
obs_register_source(&nvidia_greenscreen_filter_info);
obs_register_source(&nvidia_blur_filter_info);
obs_register_source(&nvidia_background_blur_filter_info);
}
#endif
return true;
}