Sending custom UVs to shader

Started by
1 comment, last by d h k 12 years ago
Hey there!

I'm working on a 2D game using D3D9 and HLSL. I use one single vertex buffer holding 4 vertices that describe a simple quad. These vertices also hold standard texture coordinates (from 0 to 1, as you would expect). At the moment I draw absolutely everything in the game using that tiny vertex buffer (sprites, background layers and even interface elements such as buttons) and it's extremely nice and easy to work with.

My problem is that now my artists wants me to load sprites off of sprite sheets (this is more efficient and, when working with bitmap fonts for example, really the only sane way to go) - so I don't want to split the sheets into tiny textures at load time, instead I want to be able to control the texture region that is being used by altering the texture coordinates.

I don't think switching to dynamic vertex buffers and punching in new texture coordinates for my 4 vertices makes a lot of sense so I thought it would be easiest to achieve this with a simple HLSL shader.

I can easily pass 4 vector2-type texture coordinate pairs to my shader to use for the 4 vertices of course - but I need to find a way for the shader to know which texture coordinate to use. Essentially it needs to know which vertex it is currently processing I guess (if that is possible)?

I'm familiar with HLSL and have used it for a variety of more common things (mostly lighting and deferred rendering related) but how can I achieve this particular technique? Moreover, is this really the best way to go or are there alternative ways to do what I try to do that I'm not quite seeing yet?

Thanks ahead of time, let me know if you need any additional info! I tried searching for solutions myself but have a very hard time describing my problem in 'searchable' words and phrases. Any help is greatly appreciated!
Advertisement
You need to send a Vector4 to the shader that contains the location in the texture and the size of the image located at that positoin, all these values are 0..1.

In the vertex shader you then access this to modify the texture coordinates as follows:

Vector4 textureUVInfo; //Passed from application
textureCoord.x = (in.texCoord.x * textureUVInfo.z) + textureUVInfo.x;
textureCoord.y = (in.texCoord.x * textureUVInfo.w) + textureUVInfo.y;


In the above code the actual lookup location in the texture is stored in textureUVInfo.xy and the size of that area of interest is stored in textureUVInfo.wz. All the art assets should just use 0..1 coordinates just as if they are actually textures with a single texture instead of with a spritesheet. In your application you have to store a link between a particular location and size in the texture and which object uses it.

Google Atlas texturing to find out more information as that's what a spritesheet is essentially.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

That is so smart and elegant, wow! Thanks a ton, this works flawlessly and makes a TON of sense in retrospect!

This topic is closed to new replies.

Advertisement