Friday, October 23, 2009

Adventures in virtual texture space, part 11

I've been working on implementing the texture compression ideas from the  "Real-Time Texture Streaming & Decompression" paper in my virtual texture implementation.
I couldn't just use the code and port it this time because this paper only has the decompression code, and I figured it would probably be easier to write everything from scratch then to try to figure out how the compression side would look to perfectly work with the given decompression code.
It's not implemented into my VT demo (yet), but I have some results.

Right now I can decompress an 128x128 texture in 2.5ms, and it ends up about 5-6kb, and that includes an alpha channel.
I don't think i can get it much smaller, at least i don't know how to do that without seriously degrading performance, and the quality is already less than i would like.
Eventually i'll see how much of a difference it makes when i turn this into a YCoCg/DXT5 texture, in which case there might not be much difference in quality when comparing the original and the compressed one (since DXT5 already reduces the quality)
The speed can probably be increased several times considering this is written in plain vanilla C#. Languages like C or C++ are much better at this sort of thing because you can do all kinds of pointer tricks that you cannot do easily in a managed language, although i might try C++/CLI eventually.

Like the paper I'm converting my RGB(A) texture into YCoCg(A), separate the channels, and then downsample the Co and Cg channels (which actually makes no real visual impact).
I then splice the buffers up into 8x8 blocks and pass them trough an DCT converter and quantize it all.
Unlike the paper I'm not doing run-length and Huffman encoding on a block basis, but i'm doing this over all blocks. Eventually it might make sense to do the encoding on a block basis, to make it easier to multi thread the decompression, but I'm not so sure it's a good idea to have a Huffman header on a per block basis, I'm think it would be more efficient on a per texture basis.

In the "From Texture Virtualization to Massive Parallelization" paper they mention they have "diffuse, specular, bump and cover/alpha" channels for their tiles, and that they have "Typically 2-6kB input, 40kB output".
Which makes me wonder if they have this 2-6Kb input per 'texture', or for all those channels combined.
I can't imagine that it's for all the channels combined, because 40Kb is a 128x128 texture with 2.5 bytes per texel, and they use 128x128 tile sizes as an example in the same PDF.
So it seems to me they have 2-6Kb per tile, which is about the same I have right now.
The lower limit of 2Kb is probably for grey textures that only have 1 channel.


  1. I pretty sure the 2-6kb is the size of the whole virtual page. 40kb output is 128x128, 2 dxt5, 1 dxt1 which fits. I believe the 2 to 6 kb difference is depending on whether the page is just diffuse or whether it has bump and spec. Because rage is dusty looking, spec isn't needed everywhere. They bake all the lighting so bump is only needed for the surfaces with spec. I think there is a split between just diffuse pages and full bump, spec, diffuse pages but when decoded both are put into a single general purpose physical texture probably with black spec and flat normal if the real data isn't present. There's no way for them to have full materials covering everything given the number and resolution of the virtual textures they claim they are using. The nice thing of having the data handled on a page basis is they don't need to split up geometry into types so there can be a puddle in the middle of a dirt track that has spec and it just works. 2kb per page for color is a bit better than they got in quake wars given the file sizes (2 vs ~3), but now there is padding and more time for them to have improved their methods.

  2. Hmm... okay, i guess that makes sense. A bit disappointing though, since it means that somehow my textures are 3x bigger than they should be. Considering I'm using their published methods for texture compression. Unless they've improved upon them or I'm doing something wrong, somewhere. I probably could get it 3x smaller by decreasing the quality, but that wouldn't really be a solution in my opinion.

    Do you think Rage would use bump maps for indoor areas? Because I can't imagine that it would only have static and no dynamic lighting at all.
    I suppose they could skip it for the outdoor areas which are already brightly lit.
    This would also explain why they decided to not have any day-night cycle in the game, it would simply cost too much storage space ;)

  3. All the static lighting in idTech 5 is precomputed. It is baked into the virtual texture. I don't know how much stuff has the bump maps stored but I'm guessing it is only things that are specular so that a correct reflection vector is calculated. That is used to look up in a cube map or something to fake spec with the precomputed lighting. Decompressing pages without stored bump would write out flat normals. They could also use the bump for any dynamic lighting but what I've seen in the videos looks like dynamic lights are fake and just brighten the screen. That isn't a ton worse approximation than trying to do phong lighting with a diffuse color that is just the baked lighting. Either case they have to deal with muzzle flash in a pitch black corner so some degree of fakery has to be done. I suppose you could subtract light that was baked if you wanted to turn off lights. Proper bump would be needed for that unless it was just a quick flicker. Obviously all dynamic objects such as characters need a full material because they are dynamicly lit and not baked. These things kind of stand out in the videos like the explosive barrel before it was shot because the lighting was different. It is a huge departure from doom3 where everything was dynamic and lit the same way to now almost everything is static and baked.

    As far as I'm aware all of the published compression papers by Jon Paul are for quake wars except the YCoCg in dxt5 realtime compressor. I think that work may have been done for that project but I don't know whether it was used. I really wished they talked more about their current transcoding that he touched on briefly at siggraph. It seems to me, at least, to be the most difficult part of a virtual texturing system.


To you spammers out there:
Spam will be deleted before it shows up, so don't bother.