Calculate differences between two neighbour texels

I have a texture in a fragment shader where I want to calculate the difference value between two neighbour texels in that texture.

I want to calculate it according to this formula:

bs = b[s+1,t] - b[s,t] which is along the s-coordinate and

bt = b[s,t+1] - b[s,t] which is along the t-coordinate in that texture

Now, in my fragment shader these are the essential predefined variables (I have also other variables too but I post those that are the important ones):

uniform sampler2D texUnit; //The texture map
void main(void)
{
float offset = 1.0 / 256.0; // texture size
vec2 texCoord = gl_TexCoord[0].xy; //The maps coordinates
vec4 c = texture2D(texUnit, texCoord);

float bs = ?;
float bt = ?;

}

Now from what I understand you have to access the texels in a certain way from the vector c and you want to take the s and t coordinates from that vector. But I don’t know how since that vector consists of four elements. I have been looking at various tutorial and the more I read the more confused I get. In one tutorial it says that the four-dim texture2D vector represents rgba values and in other one says it represents xyzw values. So, can you explain how I obtain the texels and calculate the differences?

bs = b[s+1,t] - b[s,t] which is along the s-coordinate and

bt = b[s,t+1] - b[s,t] which is along the t-coordinate in that texture

The texture coordinates you are using are normalized. That means the range [0, 1] cover the entire texture. Adding 1 will not access the neighboring texel.

There are several ways to do what you’re intending.

1: Use rectangle textures; these do not use normalized texture coordinates.

2: Use GLSL 1.30 or greater.

1.30 introduced the “textureOffset” texture access function. This allows you to do:


vec4 value = textureOffset(texUnit, texCoord, vec2(0, 0));
vec4 rightOneTexel = textureOffset(texUnit, texCoord, vec2(1, 0));
vec4 upOneTexel = textureOffset(texUnit, texCoord, vec2(0, 1));

Note that the offset must be a compile-time constant expression. Which for your needs is fine.

In one tutorial it says that the four-dim texture2D vector represents rgba values and in other one says it represents xyzw values.

All vectors in GLSL can be accessed with xyzw or rgba (or stpq). These all do the same thing. It’s simply a matter of convenience for you the user to be able to use rgba for colors, xyzw for positions, and stpq for texture coordinates.

Which you use changes nothing about what data you get from GLSL.

I could then use the offset variable to step through the whole texture since the texture has the size of 256 x 256 and the offset is set at 1.0/256.0 even though I am still puzzled of how to implement that calculation in the shader.

2: Use GLSL 1.30 or greater.

I won’t be necessarly be using that version since that shader code is actually a part of a lab I do in a course. You won’t be needing to use GLSL version greater than 1.1 or 1.2. It is Bump Mapping in view coordinates I am trying to do where I want to change the surface normal to

normal = normal + bsPs + btPt

Where Ps and Pt are tangentvector respective bitangentvector. Those vectors are already precalculated in the vertex shader and passed to the fragment shader. It is only bs and bt I need to implement and obviously you need to use the offset-variable in some way to access the texel values. How do I do that?

So this is homework. Why would you ask us to do your homework for you? The point of doing homework is to understand how to do these things.

No, I am not asking you to do my homework for me. It is just that I have spent a lot of time, too much time on figuring out on how to access those texels in a certain way. This is something I should have handed in a long time ago and it is driving me into madness.

I did a similar thing in Renderman SL and it was much more easier to implement the bump mapping. But now with GLSL it is much more confusing now that you have a Texture2D which is a 4D vector and you don’t know which are the st-coordinates since you specified the texunit and gl_TexCoord[0].xy as inparameters and how you want to access a neighbour texel.

I wasn’t looking for someone that can implement Bump Mapping in view coordinates for me. I know major part on how to implement that in GLSL but rather the question was to how to access a texel and its neighbour in a certain way. That is the thing I am puzzled about since I have read so many tutorials that use Texture2D in so many different ways and not mentioning about the thing I want to do what I have read so far.

Well it is simply a matter of de-normalizing texcoords back into texel units, then add/substract 1 to get neighbour, then re-normalise again. You have to pass the texture sizes as uniforms to your shader.

texCoordNeighbour.x= texCoord.x * TEX_WIDTH + 1.0 ) / TEX_WIDTH;

For better quality, consider doing your calculation in doubles on the CPU, and just upload the float delta :
your prog : ONE_OVER_TEX_WIDTH = 1.0 / texWidth;
GLSL: texCoordNeighbour.x= texCoord.x + ONE_OVER_TEX_WIDTH;