"Stretching" or "distorting" whole image with multiple sprites

I am trying to do a “spooky” shader for my 2D game. So far I made some color-effects and now I wanted to add some slight fish-eyes or something. First I tried to do this with the vertex-shader but then I get “steps” depending on the position of the 4 vertices per sprite.

So I thought that I have to use the fragment shader. I found an example where the texCoords are altered (cant link it unfortunatly). But it is for a single texture that covers the screen. How can I do this for multiple sprites, so they are all altered depending on der position? My main problem is that it is possible that I would have to draw a pixel of a texture I don’t have any information in that fragment.
So for example I am in fragment (x,y) and in fragment (x,y+1) I would normaly draw a pixel of a texture. With the distortion this pixel should be drawn by fragment (x,y) but fragment (x,y) has no information of the ID of the texture.

So both vertex and fragment shader seem impossible to use for (probably one is the right choice, as almost all games are capable of doing something similar). I tried to google but am probably too unknowing to use the technical terms. I hope it is at least clear what my problem is and am grateful for any help.

This is my clostes attempt for a fragment shader so far. But this way I still have the problem described above and the fragCoords are still wrong:

#version 330 core

in vec4 fColor;
in vec2 fTexCoords;
in float fTexId;

uniform sampler2D uTextures[8];
uniform float time;
uniform vec2 resolution;
uniform float sanity;

out vec4 color;

vec2 zoom(){
    vec2 pos = gl_FragCoord.xy / vec2(600., 800.);
    vec2 center = vec2(0.5, 0.5);
    float size = 0.4;
    vec2 dist = pos - center;
    float rad = sqrt(dot(dist, dist));

    if(rad < size){
        return (center + dist * rad);
    return pos;


void main() {
    if (fTexId > 0) {
        int id = int(fTexId);
        color = texture(uTextures[id], zoom() + fTexCoords);
        color *= darkening();
        color += vec4(vec3(flickering() * color.a), 0.0);
    } else {
        color = fColor;

Do you want the distortion effect to apply to (whole or part of) the final image of your scene or to individual sprites?
My reading of your question was that you want the former and for that it might be easiest to render your scene into a texture (instead of the back buffer) and then draw a full screen quad with that texture to the screen (i.e. back buffer) while applying the distortion effect. For rendering to a texture, see Framebuffer Object (FBO) or look for tutorials with those keywords.

This is exactly what I was searching for!
I will try the tutorial from opengl-tutorial for render to texture.

Thank you, case closed :slight_smile: