Tuesday, July 31, 2012

Hardware Instancing with Texture Atlases

I don't know why this sprang to mind... Dr. Frank-N-Furter: "He carries the Charles Atlas seal of approval."

Atlas texture.... without atlasing!  This should be one tree.
I've accomplished one last thing with the trees and instancing (I just got back from a week long business trip, can't you tell I've had all these ideas pent up?).

Having only one sort of tree at a time was a bit limiting, so I decided to try my hand at adding a bit of texture atlas functionality to my instancing.  Never tried it before, but in theory it is pretty simple.

There was always a single texture passed in to the class that set up the instancing, now it can be an atlas instead of just an ordinary texture.

Well, it could have before, it just would have been silly as you can see above.






Now, in addition, you pass in the width and height of the atlas (in textures).  Also you pass in the total number of textures (not all spots may be filled out).

So in the case where it is an ordinary texture, not an atlas, you just pass in 1, 1 and 1; everything multiplies by one, so it behaves no differently than it did pre-atlasing.  If that is a term.

I extracted the texture sampling from the pixel shaders in Instancing.fx:

float4 GetTexture(float2 inTexCoord, float2 atlasCoord, sampler texSampler)
{
float2 texCoord;

texCoord.x =  (inTexCoord.x / atlasWidth)  + (1.0f / atlasWidth  * atlasCoord.x);
texCoord.y =  (inTexCoord.y / atlasHeight) + (1.0f / atlasHeight * atlasCoord.y);



//return color, biasing the alpha up one MIP level.
return float4(tex2D(TextureSampler, texCoord).rgb,tex2Dbias(TextureSampler, float4(texCoord.xy, 1, -1)).a );
}

I got the idea of biasing up the alpha from looking at the Leaves.fx in LTrees, it does make the grass look better (or at least not disappear as quickly).

The truly surprising thing about all this was that it worked on the first try.  Never happens, normally.

Anyway this works quite well, as you can see here.  Shadows are still borked though.  But at this point I'm going to move on and start back on game and server code.  I'm sure Max will be pleased...

Edit:
I used the NVIDIA Texture Atlas Tools to make the atlas.  Made it nice and simple, outputing a dds file.  I did have to go back and regenerate the file with no MIP levels, then have the content pipeline generate them.  For some reason XNA didn't like the number of levels the NVIDIA tool generated.

Atlasing in and working!

No comments:

Post a Comment