2

Using a shader I'm trying to color a plane so it replicates the pixels on a texture. The texture is 32x32 pixels and the plane is also sized 32x32 in space coordinates.

Does anyone know how I would inspect the first pixel on the texture, then use it to color the first square (1x1) on the plane?

Generated texture example: (First pixel is red on purpose)
enter image description here

This code using a vec2 with coordinates (0,0) doesn't work as I expected. I assumed the color at (0,0) would be red but it's not, it's green:

vec4 color = texture2D(texture, vec2(0, 0));

I guess there's something that I'm missing, or not understanding about texture2D as (0,0) doesn't appear to be the ending pixel either.

If anyone could help me out, it would be greatly appriciated. Thanks.


EDIT:
Thanks for the comments and answers! Using this code, it's working now:

// Flip the texture vertically
vec3 verpos2 = verpos.xyz * vec3(1.0, 1.0, -1.0);

// Calculate the pixel coordinates the fragment belongs to
float pixX = floor(verpos2.x - floor(verpos2.x / 32.0) * 32.0);
float pixZ = floor(verpos2.z - floor(verpos2.z / 32.0) * 32.0);

float texX = (pixX + 0.5) / 32.0;
float texZ = (pixZ + 0.5) / 32.0;

gl_FragColor = texture2D(texture, vec2(texX, texZ));

That said, I'm having an issue with jagged lines on the edges of each "block". Looks to me like my math is off and it's confused about what color the sides should be, because I didn't have this problem when using only vertex colors. Can anyone see where I've gone wrong or how it could be done better?
Thanks again!

enter image description here

Joey Morani
  • 25,431
  • 32
  • 84
  • 131
  • If you have GL-ES 3.0 you can use ['texelFetch'](http://www.khronos.org/opengles/sdk/docs/manglsl/xhtml/texelFetch.xml). Otherwise, [this](http://stackoverflow.com/questions/5879403/opengl-texture-coordinates-in-pixel-space) answer may help. – Brett Hale Oct 24 '13 at 17:53
  • Thanks for the link. Apparently WebGL doesn't support texelFetch, so unfortunately I can't use that :( – Joey Morani Oct 24 '13 at 18:07
  • 2
    I believe that OpenGL ES' coordinate system begins from the bottom left -- on iOS, it is sometimes necessary to vertically flip images. – Ben Pious Oct 24 '13 at 20:02

1 Answers1

2

Yes... as Ben Pious mentioned in a comment, remember that WebGL displays 0,0 in lower left.

Also, for indexing into your textures, try to sample from the "middle" of each pixel. On a 32x32 source texture, to get pixel (0,0) you'd want:

texture2D(theSampler, vec2(0.5/32.0, 0.5/32.0));

Or more generally,

texture2D(theSampler, vec2((xPixelIndex + 0.5) / width, (yPixelIndex + 0.5) / height);

This is only if you're explicitly accessing texture pixels; if you're getting values interpolated and passed through from the vertex shader (say a (-1,-1) to (1,1) square, and pass varying vec2((x+1)/2,(y+1)/2) to the fragment shader), this "middle of each pixel" is reflected in your varying value.

But it's probably just the Y-up like Ben says. :)

david van brink
  • 3,604
  • 1
  • 22
  • 17
  • Thanks again for answering. :P Did what you and Ben Pious said and it's working now, but having a problem with jagged lines. If you're willing to help me again I've edited my question. :) – Joey Morani Oct 25 '13 at 13:22
  • Back at the office, I'd put, "pls close original bug as fixed, and file new one for new issue" :-) I'm not totally sure what your new code is doing, but maybe all the floors and such are not needed; they may be thwarting WebGL's interpolation. You might try just texture2D(texture, vec2(verpos2.x, verpos2.z)); It looks like those are coming in with range 0..31? – david van brink Oct 25 '13 at 22:12
  • 1
    Got it figured out now. Thanks David. :) – Joey Morani Oct 25 '13 at 23:04