nleseul / obs-shaderfilter

OBS Studio filter for applying an arbitrary shader to a source.
The Unlicense
101 stars 119 forks source link

Blur filter #1

Open vico93 opened 6 years ago

vico93 commented 6 years ago

Hi! Is possible to make a source blurred with this plugin? If yes, can you bundle a sample shader with the standard release?

Thanks a lot!

nleseul commented 6 years ago

Here's a basic blur shader, as described here:

// Basic 9-tap Gaussian blur, applied in one direction. Apply in pairs, with blur_vertical set on every other
// instance, to get a two-dimensional blur.
// Based on: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson5

uniform bool blur_vertical;

float4 mainImage(VertData v_in) : TARGET
{
    float4 sum = float4(0, 0, 0, 0);

    float hstep = !blur_vertical * uv_pixel_interval.x;
    float vstep = blur_vertical * uv_pixel_interval.y;

    sum += 0.0162162162 * image.Sample(textureSampler, float2(v_in.uv.x - 4 * hstep, v_in.uv.y - 4 * vstep));
    sum += 0.0540540541 * image.Sample(textureSampler, float2(v_in.uv.x - 3 * hstep, v_in.uv.y - 3 * vstep));
    sum += 0.1216216216 * image.Sample(textureSampler, float2(v_in.uv.x - 2 * hstep, v_in.uv.y - 2 * vstep));
    sum += 0.1945945946 * image.Sample(textureSampler, float2(v_in.uv.x - 1 * hstep, v_in.uv.y - 1 * vstep));

    sum += 0.2270270270 * image.Sample(textureSampler, v_in.uv);

    sum += 0.1945945946 * image.Sample(textureSampler, float2(v_in.uv.x + 1 * hstep, v_in.uv.y + 1 * vstep));
    sum += 0.1216216216 * image.Sample(textureSampler, float2(v_in.uv.x + 2 * hstep, v_in.uv.y + 2 * vstep));
    sum += 0.0540540541 * image.Sample(textureSampler, float2(v_in.uv.x + 3 * hstep, v_in.uv.y + 3 * vstep));
    sum += 0.0162162162 * image.Sample(textureSampler, float2(v_in.uv.x + 4 * hstep, v_in.uv.y + 4 * vstep));

    return sum;
}

You'll need to apply two of them to your source, one horizontal and one vertical.

This is a fixed-size blur with a radius of 4 pixels, so the effect isn't very strong. You should be able to apply multiple pairs to strengthen the effect, but watch your GPU usage.

I can probably put this into the next release, whenever I do that.

vico93 commented 6 years ago

Thanks. I was trying to "port" this shader to OBS Studio via your plugin, but apparently it doesnt work.

davboecki commented 6 years ago

I've been playing around with this Plugin an some blur effects, maybe this can help you: I've looked at the plugin you linked and created a shader to apply blur in both directions at the same time, which is a lot stronger than the original one.

float4 mainImage(VertData v_in) : TARGET
{
    float4 sum = float4(0, 0, 0, 0);
    const float weights[21] = { 0.000539, 0.001533, 0.003908, 0.008925, 0.018255, 0.033446, 0.054891, 0.080693, 0.106259, 0.125337, 0.132429, 0.125337, 0.106259, 0.080693, 0.054891, 0.033446, 0.018255, 0.008925, 0.003908, 0.001533, 0.000539 };

    for (int x = 0; x < 21; x++)
    {
        int xO = x - 10;
        for (int y = 0; y < 21; y++)
        {
            int yO = y - 10;
            sum += weights[x] * weights[y] * image.Sample(textureSampler, float2(v_in.uv.x - xO * uv_pixel_interval.x, v_in.uv.y - yO * uv_pixel_interval.y));
        }
    }

    return sum;
}

This can of course be addapted as it is has a high GPU usage. With the original weights from the BlowserPlugin you get:

float4 mainImage(VertData v_in) : TARGET
{
    float4 sum = float4(0, 0, 0, 0);
    const float weights[11] = { 0.000003, 0.000229, 0.005977, 0.060598, 0.24173, 0.382925, 0.24173, 0.060598, 0.005977, 0.000229, 0.000003 };

    for (int x = 0; x < 11; x++)
    {
        int xO = x - 5;
        for (int y = 0; y < 11; y++)
        {
            int yO = y - 5;
            sum += weights[x] * weights[y] * image.Sample(textureSampler, float2(v_in.uv.x - xO * uv_pixel_interval.x, v_in.uv.y - yO * uv_pixel_interval.y));
        }
    }

    return sum;
}

And for anybody who wants to use costum sizes and wights: The size has to have a center, so you need to chose a radius multiply it by 2 and add 1 to get your size. Example:

radius = 5
size = radius * 2 + 1 = 11

you can see the values 5 and 11 in the example above. Just replace them with your new values. Now you only need to update the weights, for which you can use this: http://dev.theomader.com/gaussian-kernel-calculator/. There you can also play around with the sigma value. In the end just copy the "One dimensional Kernel" values over into the weights array, and don't forget to add "," between the values.

Drakonas commented 6 years ago

Is there a way to enable this Blur on certain scenes only? It seems that per-scene filter settings are not possible yet with OBS itself. :/

Andersama commented 6 years ago

For blurs, you guys may want to consider a two pass hlsl shader btw, saves on the sampling.

vico93 commented 6 years ago

Where i could find this?