Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose rectangle start position to shaders #146

Open
necauqua opened this issue Jun 26, 2021 · 6 comments
Open

Expose rectangle start position to shaders #146

necauqua opened this issue Jun 26, 2021 · 6 comments

Comments

@necauqua
Copy link

Lack of this severely limits shaders as they have no idea where the selection rectangle is.

So some basic ideas, like blurring the rest of the screen, are not currently possible.

Rectable does not exist until the selection is started, so something like current state index should also be visible from shaders as well, I think.

@meganukebmp
Copy link

I second this. Would be really nice to have the two rectangle vec2s for start and end position.
This would allow for complex shaders such as mentioned above, blurring everything but the selection region.
What I'm interested in is having both a white selection border and a black background dim for example. With the currently exposed shader parameters this is impossible.

This functionality can further tie into #148. Since knowing start and end would allow us to display coordinates easily in a shader

@meganukebmp
Copy link

A bit of a necro at this point, but I'd like to come back and share that having a blur for everything but the area is perfectly doable! If you use the -l option and do some math. Here is the shader:

#version 120

uniform sampler2D texture;
uniform sampler2D desktop;
uniform vec2 screenSize;

varying vec2 uvCoord;

// Stolen from https://github.com/Jam3/glsl-fast-gaussian-blur kinda
void main()
{
    float radius = 3;
    vec2 upsideDownUV = vec2( uvCoord.x, -uvCoord.y );
    vec4 color = vec4(0.0);
    vec2 off1 = vec2(1.411764705882353) * vec2( radius, 0 );
    vec2 off2 = vec2(3.2941176470588234) * vec2( radius, 0 );
    vec2 off3 = vec2(5.176470588235294) * vec2( radius, 0 );

    vec4 rect = texture2D(texture,uvCoord);
    vec4 irect = (vec4(1,1,1,1) - rect);

    color += texture2D(desktop, upsideDownUV) * 0.1964825501511404;
    color += texture2D(desktop, upsideDownUV + (off1 / screenSize)) * 0.2969069646728344;
    color += texture2D(desktop, upsideDownUV - (off1 / screenSize)) * 0.2969069646728344;
    color += texture2D(desktop, upsideDownUV + (off2 / screenSize)) * 0.09447039785044732;
    color += texture2D(desktop, upsideDownUV - (off2 / screenSize)) * 0.09447039785044732;
    color += texture2D(desktop, upsideDownUV + (off3 / screenSize)) * 0.010381362401148057;
    color += texture2D(desktop, upsideDownUV - (off3 / screenSize)) * 0.010381362401148057;
    color = (color - vec4(0.1, 0.1, 0.1, 0)) * irect;

    vec2 pixel = vec2(1,1)/screenSize;
    
    vec4 up = texture2D(texture, vec2(uvCoord.x, uvCoord.y+pixel.y));
    vec4 down = texture2D(texture, vec2(uvCoord.x, uvCoord.y-pixel.y));
    vec4 left = texture2D(texture, vec2(uvCoord.x-pixel.x, uvCoord.y));
    vec4 right = texture2D(texture, vec2(uvCoord.x+pixel.x, uvCoord.y));

    if (rect.a == 0 && (up.a + down.a + left.a + right.a) > 0) {
        color = vec4(1,1,1,1);
    }

    gl_FragColor = (color);
}

Which looks like this
image

@necauqua
Copy link
Author

necauqua commented Mar 17, 2023

Huh, I actually still use maim, so this works, thanks!
One thing is that the blur in your shader is pretty obsiously, hmm, x-biased?. Can you see what I mean by that? I am failing to understand/fix it so far.
So the blur implementation you used is directional 😅
And you give it the direction vec2(radius, 0), I'll have to look for some other blur :)

@meganukebmp
Copy link

meganukebmp commented Mar 17, 2023

One thing is that the blur in your shader is pretty obsiously, hmm, x-biased?. Can you see what I mean by that?

I took the blur from the existing blur example shader. Feel free to use another one if you have one. Do post results here if you make something better. Cheers!

@meganukebmp
Copy link

meganukebmp commented Mar 18, 2023

Try this. This is untested mind you. Whipped it up in shadertoy. It should in theory work ootb. It's very slow tho. Play with Depth, offsetDist and Samples. This is a radial blur.

#version 120

uniform sampler2D texture;
uniform sampler2D desktop;
uniform vec2 screenSize;

varying vec2 uvCoord;

// Blur taken from https://www.shadertoy.com/view/3ljBDd
const float Depth = 3.;
const float OffsetDist = 8.;
const float Samples = 16.;

#define TAU 6.28318530718

vec4 RadialBlur(vec2 uv, float radius, sampler2D sampler) {

    if(radius <= 0.) return texture2D(sampler, uv);
    vec2 offset;
    float angle = 0.;
    vec4 color = vec4(0.);
    for(float angle = 0.; angle < TAU; angle += (TAU/Samples)) {

        offset = vec2(cos(angle), sin(angle)) * radius;
        color += texture2D(sampler, (uv + offset/screenSize));

    }

    return color/Samples;

}

vec4 FastBlur(vec2 uv, sampler2D sampler) {

    vec4 color;
    vec2 offset;
    float fib = 2.;
    float fibTotal = 0.;

    for(float i = 1.; i <= Depth; ++i) {
        fib += i;
        color += RadialBlur(uv, i * OffsetDist, sampler)/ fib;
        fibTotal += 1./fib;
    }

    return color/fibTotal;

}


void main()
{
    float radius = 3.0;

    vec2 upsideDownUV = vec2( uvCoord.x, -uvCoord.y );

    vec4 rect = texture2D(texture,uvCoord);
    vec4 irect = (vec4(1,1,1,1) - rect);

    vec2 pixel = vec2(1,1)/screenSize;

    vec4 up = texture2D(texture, vec2(uvCoord.x, uvCoord.y+pixel.y));
    vec4 down = texture2D(texture, vec2(uvCoord.x, uvCoord.y-pixel.y));
    vec4 left = texture2D(texture, vec2(uvCoord.x-pixel.x, uvCoord.y));
    vec4 right = texture2D(texture, vec2(uvCoord.x+pixel.x, uvCoord.y));

    vec4 bg = texture2D(desktop, upsideDownUV);
    vec4 bgblur = FastBlur(upsideDownUV, desktop) * vec4(vec3(0.7),1);

    vec4 color = bgblur * irect;

    if (rect.a == 0.0 && (up.a + down.a + left.a + right.a) > 0.0) {
        color = vec4(vec3(1,1,1) - bg.rgb, 1.0);
    }

    gl_FragColor = (color);
}

@meganukebmp
Copy link

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants