2
$\begingroup$

I am working with an atlas shader that steps through various sprite tiles within a single png atlas page to playback an animation with sampler2D. Looking at the shader code, I would expect to have to define a lower left and upper right point for each image area on the atlas image that I want to use for that frame. However, it simply uses a Vec2 which is just a single x,y value. How is this possible? How is a single vec2 defining both position and range of the sampled area? In a more broad sense how are these UV vec2s from varying UVs being interpreted in GLSL in general? To me, you can't define an image area from just a vec2 so I am really confused???

$\endgroup$
0

1 Answer 1

1
$\begingroup$

It's hard to say without seeing the shader in question. My guess is that every animation frame in the atlas has the same size. This fixed size allows mapping any UV coordinates to the proper animation frame's UV extents.

For example, with 16 frames in a texture:

0 0.25 0.5 0.75 1.0
\  \   |   /  _/
 +--+--+--+--+
 | 0| 1| 2| 3|
 +--+--+--+--+ 0.25
 | 4| 5| 6| 7|
 +--+--+--+--+ 0.5
 | 8| 9|10|11|
 +--+--+--+--+ 0.75
 |12|13|14|15|
 +--+--+--+--+ 1.0

This code should do the trick to convert UV coordinates (range [0, 1]) to a given frame's UV extents:

vec2 uv = ...
uint frameId = ... // [0, 15]
const uint rowFrameCount = 4; // implies frameUVWidth = 1 / 4 = 0.25
const vec2 frameUVSize = vec2(1.0 / rowFrameCount, 0.25);

// Find the column and row offset
uvec2 frameOffset = uvec2(frameId % rowFrameCount, frameId / rowFrameCount);

// Offset to the proper column
uv += frameOffset;

// Scale the coordinates in the range of a single frame (here [f_0, f_0 + 0.25])
uv *= frameUVSize;

Some results:

uv = vec2(0, 1); frameId = 0; uv_out = vec2(0, 0.25);
uv = vec2(0, 0.5); frameId = 3; uv_out = vec2(0.75, 0.125);
uv = vec2(0.5, 0.5); frameId = 14; uv_out = vec2(0.625, 0.875);

In truth however, this kind of texture trickery is less useful these days since array textures are now widely available with better results and simpler indexing.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.