- Home /
How to locate the correct texture within a texture atlas using a shader?
Hi, I am beginning to learn shader programming. I have been doing some stuff with vertex, geometry and computational shaders. But in god's name, I can't understand and couldn't find a clear, concise answer to that simple thing: how to locate a specific texture within a texture atlas, inside a shader?
I have found questions and answers about how to access a specific texture from an atlas outside shaders. I have found extensive discussions on tiling, wrapping, etc. But I did not find a simple explanation of simply how to locate a texture within an atlas inside the shader code.
For instance, suppose I have 4 textures of 128x128 each. Displayed in an atlas in a 2x2 fashion (so the atlas has 256x256). What is the correct way to make the shader access each of these 4 pieces of the atlas (let's call them A, B, C and D, starting at the left-up, and then gong clockwise).
Thanks for any help!
Answer by FortisVenaliter · May 18, 2016 at 04:16 PM
Generally, this is done through the texture coordinates in the vertex shader. You can shift and scale them as needed. So, in your example, you would pass in texture coordinates for the whole texture: (0,0) (1,0) (1,1) (0,1), then in the vertex shader, scale and offset them. For example, the top right image would be (0.5, 0) (1,0) (1,0.5) (0.5, 0.5). Or, it could be represented by the following equation:
newX = (srcX / numImgX) + (offsetX * 1/numImgX);
newY = (srcY / numImgY) + (offsetY * 1/numImgY);
But, you'll need to pass in that information about the texure atlas (how many images it contains, etc), as well as information telling the shader which image to use.
Thanks for the quick reply to my question! $$anonymous$$y main problem is exactly where at the shader I should inform that position of the image I want. I mean, I know how to inform the shader about the number of images in the atlas and which image in the atlas I want to use. However, my main problem is exactly how, i.e. in which command with which parameter should I inform the coordinates of the 4 corners of the image in the atlas? Because so far I have always used only one image (no atlas) with the command tex2D like in tex2D(_texname, input.uv). Which means, passing only one coordinate in a float2 as parameter, never 4 coordinates.
PS: in your example (0.5, 0) (1,0) (1,0.5) (0.5, 0.5), shouldn't it be the bottom-right image ins$$anonymous$$d of the top right, or did I get the coordinate system wrong?
Should be top right. 0 is top Y/V, 1 is bottom Y/V.
You would need to pass it in, not through the model, but as a global shader variable, like the way you pass in the texture. Then it will show up as a parameter in the regular shader inspector/code that you can set before drawing your object.
Are you found the solution finally ?
Could you share a shader if you did ?