我参考了 github 上的OBS Studio 20.1.0 文档和chroma_key_filter.effect。最近自制的 obs-studio 过滤器有问题。我想不出如何解决它。在这里想请教大家,希望能得到一些建议或答案。
第一个问题是,当捕捉到power point演示文稿时,背景设置为红色(图1),然后我可以用我自己的边缘检测内核得到文本的边缘,但是通常的绿色(或蓝色)颜色会不会显示效果(图2)?(OBS-studio资源为了方便看效果使用了白色背景)在 此输入图片说明 图1。
在此处输入图像描述 图 2。
第二个问题是过滤器已更改为其他内核。相反,参数化的水平滚动条没有任何作用。是否需要调整位置才能使全罩工作(图 3)? 在此处输入图像描述 图 3。
代码展示如下(其编程语言使用HLSL或GLSL语言):
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float4x4 yuv_mat = { 0.182586, 0.614231, 0.062007, 0.062745,
-0.100644, -0.338572, 0.439216, 0.501961,
0.439216, -0.398942, -0.040274, 0.501961,
0.000000, 0.000000, 0.000000, 1.000000};
uniform float4 color;
uniform float contrast;
uniform float brightness;
uniform float gamma;
uniform float2 chroma_key;
uniform float4 key_rgb;
uniform float2 pixel_size;
uniform float similarity;
uniform float smoothness;
uniform float spill;
// 3x3 kernel for convolution edge detection.
uniform float3 kernel1 = { -1.0, -1.0, -1.0};
uniform float3 kernel2 = {-1.0, 8.0, -1.0};
uniform float3 kernel3 = {-1.0, -1.0, -1.0 };
sampler_state textureSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0; //Texture coordinates.
};
VertData VSDefault(VertData v_in)
{
VertData vert_out;
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = v_in.uv;
return vert_out;
}
float4 CalcColor(float4 rgba)
{
return float4(pow(rgba.rgb, float3(gamma, gamma, gamma)) * contrast + brightness, rgba.a);
}
float GetChromaDist(float3 rgb)
{
float4 yuvx = mul(float4(rgb.rgb, 1.0), yuv_mat); //rgb to yuv
return distance(chroma_key, yuvx.yz); // Take the distance scalar value of two vectors.
}
float4 SampleTexture(float2 uv)
{
return image.Sample(textureSampler, uv);
}
// 3x3 filter of Edge detection
float GetEdgeDetectionFilteredChromaDist(float3 rgb, float2 texCoord)
{
float distVal = SampleTexture(-texCoord-pixel_size).rgb * kernel1[0]; // Top left
distVal += SampleTexture(texCoord-pixel_size).rgb * kernel1[1]; // Top center
distVal += SampleTexture(texCoord-float2(pixel_size.x, 0.0)).rgb * kernel1[2]; // Top right
distVal += SampleTexture(texCoord-float2(pixel_size.x, -pixel_size.y)).rgb * kernel2[0]; // Middle left
distVal += SampleTexture(texCoord-float2(0.0, pixel_size.y)).rgb * kernel2[1]; // Current pixel
distVal += SampleTexture(texCoord+float2(0.0, pixel_size.y)).rgb * kernel2[2]; // Middle right
distVal += SampleTexture(texCoord+float2(pixel_size.x, -pixel_size.y)).rgb * kernel3[0]; // Bottom left
distVal += SampleTexture(texCoord+float2(pixel_size.x, 0.0)).rgb * kernel3[1]; // Bottom center
distVal += SampleTexture(texCoord+pixel_size).rgb * kernel3[2]; // Bottom right
return distVal;
}
float4 ProcessChromaKey(float4 rgba, VertData v_in)
{
float chromaDist = GetEdgeDetectionFilteredChromaDist(rgba.rgb, v_in.uv);//Edge detection filter function.
float baseMask = chromaDist - similarity;
float fullMask = pow(saturate(baseMask / smoothness), 1.5);
float spillVal = pow(saturate(baseMask / spill), 1.5);
rgba.rgba *= color;
rgba.a *= fullMask;
float desat = (rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722);
rgba.rgb = saturate(float3(desat, desat, desat)) * (1.0 - spillVal) + rgba.rgb * spillVal;
return CalcColor(rgba);
}
float4 PSChromaKeyRGBA(VertData v_in) : TARGET
{
float4 rgba = image.Sample(textureSampler, v_in.uv);
return ProcessChromaKey(rgba, v_in);
}
technique Draw
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSChromaKeyRGBA(v_in);
}
}
谢谢!