Search code examples
glslshaderwebgl

Given a coordinate in 2D clipspace, how can i sample the background texture


Consider a texture with the same dimensions as gl.canvas, what would be the proper method to sample a pixel from the texture at the same screen location as a clip-space coordinate (-1,-1 to 1,1)? Currently i'm using:

//u_screen = vec2 of canvas dimensions
//u_data = sampler2D of texture to sample
vec2 clip_coord = vec2(-0.25, -0.25);
vec2 tex_pos = (clip_coord / u_screen) + 0.5;
vec4 sample = texture2D(u_data, tex_pos);

This works but doesn't seem to properly take into account the canvas size and text_pos seems offset the closer clip_coord gets to -1 or 1.


Solution

  • In the following is assumed that the texture has the same size as the canvas and is rendered 1:1 on the entire canvas, as mentioned in the question.

    If clip_coord is a 2 dimension fragment shader input where each component is in range [-1, 1], then you've to map the coordinate to the range [0, 1]:

    vec4 sample = texture2D(u_data, clip_coord*0.5+0.5);
    

    Note, the texture coordinates range from 0.0 to 1.0.


    Another possibility is to use gl_FragCoord. gl_FragCoord is a fragment shader built-in variable and contains the window relative coordinates of the fragment.

    If you use WebGL 2.0 respectively GLSLES 3.00,
    then gl_FragCoord.xy can be use for texture lookup of a 2 dimensional texture, by texelFetch, to get the texel which correspond to the fragment:

    vec4 sample = texelFetch(u_data, ivec2(gl_FragCoord.xy), 0);
    

    Note, texelFetch performs a lookup of a single texel. You can think about the coordinate as the 2 dimensional texel index.

    If you use WebGL 1.0 respectively GLSL ES 1.00,
    then gl_FragCoord.xy can divided by the (2 dimensional) size of the texture. The result can be used for a texture lookup, by texture2D, to get the texel which correspond to the fragment:

    vec4 sample = texture2D(u_data, gl_FragCoord.xy / u_size);