Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OpenGL ES 2.0, How to read neighboring texels from a Sampler?

I am passing a texture with NxM size as a sampler in the GLSL fragment shader (OpenGL ES 2.0). What is the right way to read the texel data from the neighboring texel ? I do not have a "varying" texture coordinate in the fragment shader. I can only use fragment coordinate to read the texture information.

following is my shader, I am not sure if its actually reading the data:

precision mediump float;

uniform sampler2D Sampler;

#define OFFSET 1.0

void main()
{

    vec2 T = gl_FragCoord.xy;

    //Find neighboring velocities:
    vec2 N = texture2D(Sampler,vec2(T.x,T.y+OFFSET)).xy;
    vec2 S = texture2D(Sampler,vec2(T.x,T.y-OFFSET)).xy;
    vec2 E = texture2D(Sampler,vec2(T.x+OFFSET,T.y)).xy; 
    vec2 W = texture2D(Sampler,vec2(T.x-OFFSET,T.y)).xy; 
}

Is the OFFSET value should be 1.0 OR something else for NxM size texture ?

like image 898
kal21 Avatar asked Oct 14 '11 22:10

kal21


2 Answers

Nem is right in his answer that the texture coordinate should be in [0,1]. But keep in mind, that the values of gl_FragCoord are in [0,N]x[0,M] (assuming your viewport is NxM, too). So you are correct in adding an offset of 1 to the fragment coordinate, but this sum has then to be divided by the screen size (which is probably the same as the texture size):

precision mediump float;

uniform sampler2D Sampler;
uniform vec2 invScreenSize;

void main()
{

    vec2 T = gl_FragCoord.xy;

    //Find neighboring velocities:
    vec2 N = texture2D(Sampler,vec2(T.x,T.y+1.0)*invScreenSize).xy;
    vec2 S = texture2D(Sampler,vec2(T.x,T.y-1.0)*invScreenSize).xy;
    vec2 E = texture2D(Sampler,vec2(T.x+1.0,T.y)*invScreenSize).xy; 
    vec2 W = texture2D(Sampler,vec2(T.x-1.0,T.y)*invScreenSize).xy; 
}

where invScreenSize is the reciprocal screen size (1/N, 1/M), to prevent division in the shader.

like image 171
Christian Rau Avatar answered Sep 18 '22 15:09

Christian Rau


I'm pretty sure that in OpenGL ES 2.0 all texture coordinates are floats between 0.0 and 1.0, so adding 1.0 will be wrong, and will probably just wrap around to the exact same position. Your x offset should be 1.0/N and your y offset should be 1.0/M (based on your NxM statement). I am not confident that this is the best solution, but I have used it to solve a similar problem.

I would advise that you check the OpenGL ES Shading Language specification to verify that my claim about the texture coordinate format is correct (I did this a few months ago). It's a pdf that is easy to find with google, and has a convenient list of all the built-in functions somewhere.

like image 42
Nem Avatar answered Sep 17 '22 15:09

Nem