1
votes

In my shader I already have a special variable that has the entire content of previously rendered screen. It is stored in

uniform sampler2D _GrabTexture;

Which it's content should be: Screen content

(As a side note, I'm using Unity's GrabPass{} to get the entire screen. Also please ignore Unity's GUI)

Now how can I render one more pass, using _GrabTexture as a texture for my plane model, so the result is exactly the same as my _GrabTexture?

(The point is, I can apply some effects like blur,sharpen,etc to that screen texture before render one more pass so the plane's texture is now stylized.)

I'm trying this in the final pass. The variable is declared in both Vertex & Fragment Shader.

uniform sampler2D _GrabTexture;
varying vec4 v_Position;

Vertex Shader :

void main()
        {
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
            v_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

        }

Store the screen coordinate of each model's vertex as varying, to be used in Fragment Shader.

Fragment Shader :

void main()
        {
            gl_FragColor = texture2D(_GrabTexture,vec2(v_Position)); 
        }

Now use that stored varying position to access the _GrabTexture screen texture. Since it's entire screen my v_Position which is already in screen coordinate should correctly got the right pixel.

But the result is

enter image description here

As you can see the plane's texture is 'sorts of' showing previously rendered screen but the coordinate is not right. How can I fix it so the result is the same as first image?

1

1 Answers

4
votes

You're thinking too complicated. OpenGL tells you the on-screen fragment position in the fragment shader built in variable gl_FragCoord.

With GLSL-1.30 or newer you have texelFetch which you can give gl_FragCoord as source coordinate directly. Or you use translate gl_FragCoord into texture space coordinates, see https://stackoverflow.com/a/5879551/524368