Skip to main content
gamedev.net
🔒 Locked

Texture coordinates

Started by sprite_hound Jul 16, 2008 at 3:43 PM 3 replies 800+ views
Original Post
sprite_hound
sprite_hound
This is perhaps a pretty basic issue, but I've been getting more and more confused over it lately, and don't seem to be able to find anything that explains it clearly and authoratatively on the net. How should I be finding a certain pixel in a texture in a (vertex) shader? Lets say I have a set of vertices from 0 to 7 (8 vertices), that I want to correspond with one of 8 pixels in a texture. To find the texture coordinates do I do: n / (tot - 1) where n is the number of the vertex (0 to 7), and tot is the total number of vertices (8) - so mapping from 0.0 to 1.0 in steps of 0.142... (treating the pixels as data points spread between 0.0 and 1.0 I suppose). Or do I do something like: n / tot + 0.5 * 1.0 / tot which maps from 0.0625 to 0.9375 in steps of 0.125 (and thus put the vertices in the "middle of the pixels"). The more I write of this the more convinced I am it's the second one, but I'd like someone to confirm it.
spek
spek
I bounced my head several times with 3D texture coordinates lately. Instead of interpolating in between, I needed the exact pixel coordinates like you did. I'm not 100% either, but I think you'll need to add "half a pixel". At least, I needed to do that for my 3D texture Z coordinates, otherwise it would fall in between. Thus:
texcoord.x = x * (1 / totalPixelsWidth) + (0.5 / totalPixelsWidth);


Ow, maybe I was hallucinating because of the texture coordinate madness combined with spherical harmonics, but I believe I had to be carefull with dividing. For example:
x * (1/8)
x / 8
x * 0.125
should be the same, but in some cases only the last line worked. Either I still did something wrong, or the Cg compiler has bugs (notice it was a huge and complicated shader).

Greetings,
Rick
sprite_hound
sprite_hound
Thanks Rick.

Yep, addding the half pixel offset does seem to be correct. (At least, I've now been able to get rid of a dodgy hack in my shader code because of it).
LeGreg
LeGreg
That's not true, you don't need to add half a texel to your texture coordinate, but you need to substract half a pixel to your screen coordinates.

This has been repeated again :
Directly mapping texels to pixels
and again :
Mapping texels to pixels

The reason, the "add half a texel" version does not work, is that if you start your quad on an "integer value" then it's going to cover only half (or a quarter) of the first pixel square. Whereas if you substract "half a pixel" to your starting coordinates, it will cover your entire pixel, like it would in OpenGL and D3D10.

Following the two docs above (they pretty much say the same thing in different wording) you will avoid weird alignment bugs that your current approach would cause.

Also if you need exact values, don't forget to set the filter to nearest/point as bilinear even with seemingly correct texcoords and screen coords will slightly alter your values.

LeGreg
sprite_hound
sprite_hound
Quote:
Original post by LeGreg
That's not true, you don't need to add half a texel to your texture coordinate, but you need to substract half a pixel to your screen coordinates.

This has been repeated again :
Directly mapping texels to pixels
and again :
Mapping texels to pixels

The reason, the "add half a texel" version does not work, is that if you start your quad on an "integer value" then it's going to cover only half (or a quarter) of the first pixel square. Whereas if you substract "half a pixel" to your starting coordinates, it will cover your entire pixel, like it would in OpenGL and D3D10.


I probably should have made this clearer, but I'm not using window / screen space (which both those links seem to be refering to), but object / world space in the vertex shader. i.e. I'm effectively using the texture as vertex attributes for a grid. So the correspondence between texels and pixels isn't relevant.

I therefore stick by my second way of working out the uv's, which works nicely.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.