在OpenGL ES 2.0中,如何从采样器读取相邻的纹素?

时间:2011-10-14 22:46:07

标签: opengl-es glsl opengl-es-2.0

我在GLSL片段着色器(OpenGL ES 2.0)中传递具有NxM大小的纹理作为采样器。从相邻纹理元素读取纹素数据的正确方法是什么?我在片段着色器中没有“变化的”纹理坐标。我只能使用片段坐标来读取纹理信息。

以下是我的着色器,我不确定它是否实际读取数据:

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; 
}

对于NxM尺寸纹理,OFFSET值是否应为1.0或其他值?

2 个答案:

答案 0 :(得分:14)

Nem在他的回答中是正确的,纹理坐标应该在[0,1]中。但请记住,gl_FragCoord的值在[0,N] x [0,M]中(假设您的视口也是NxM)。因此,在片段坐标中添加1的偏移是正确的,但是这个总和除以屏幕大小(可能与纹理大小相同):

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; 
}

其中invScreenSize是互惠屏幕尺寸(1/N, 1/M),以防止着色器中的分割。

答案 1 :(得分:4)

我很确定在OpenGL ES 2.0中,所有纹理坐标都在0.0到1.0之间浮动,因此添加1.0将是错误的,并且可能只是环绕到完全相同的位置。您的x偏移量应为1.0 / N,y偏移量应为1.0 / M(基于您的NxM语句)。我不相信这是最好的解决方案,但我用它来解决类似的问题。

我建议您检查一下OpenGL ES着色语言规范,以验证我对纹理坐标格式的说法是否正确(我几个月前做过这个)。这是一个很容易用谷歌找到的PDF格式,并且在某个地方有一个方便的所有内置函数列表。