Wednesday, September 23, 2009

Adventures in virtual texture space, part 6 B

As promised in my last post, here's a video of what i got so far.

Random thought:
I'm wondering if it would be useful to have automatically generated page 'samples' spread around the level, each containing a list which pages are near it. That way it would be relatively simple to 'look ahead' and determine which pages could potentially be required in the near future.

The samples would contain all the pages for a specific miplevel in all directions and limited to the distance to the sample where a miplevel would be used.

Since this would only be possible for static pages / geometry, pages for dynamic objects would have to be handled differently.

Potentially, this could remove the need to do a readback completely..

But would this approach be faster? It could be more accurate though.

Maybe navigation meshes, if they're accurate enough, could be used to simplify the process of creating the samples.
The same information could be used to determine which pages could never be visible.
It would look pretty horrible when some pages are missing but turn out to be visible after all though.


  1. Great work. You inspired me to work on my implementation again. I have one question though. How do you handle cracks between pages? In my implementation I have cracks between pages that increase as the mip levels decrease. I'm not talking about the problem with linear interpolation because the tiles are non continuous. Do you remap the texture coordinates at all? I think you would have the same problem with any texture atlas. I don't see any cracks in your implementation. Thanks.

  2. Actually there are some cracks in this video, but these are the linear interpolation kind. I forgot to mention that i didn't put in a border around my pages yet. These seams would be completely invisible if i used a texture-array, but unfortunately then i would be limited to 512 pages.

    I'm not sure what you mean with cracks between miplevels, i never had any problems with that unless i have different colored pages at each miplevel. Can you elaborate?

    I don't remap texture coordinates as such, I pretend that my UV coords span the entire virtual texture, and i then calculate which page at which miplevel i should be rendering. I then use a indirection (lookup) table, to fetch the page-id/page-coords/page-dimensions to determine where I should get my texel from.
    This is just a couple of lines of shader code.

    I'm sure you've already looked at Sean Barrett's "sparse virtual texture"? And the presentations from Id software and Crytek?

  3. The problem is a crack appears between pages that gets worse with the change in mip levels.

    My code is: frac( input.uv * PageTableSize / CurrentMipSize ).

    I actually started with Sean's shader. I stripped out the atlas related stuff because I'm using texture arrays until I nail this problem. I'm thinking it's some simple "off by one" error somewhere.

    Here's a couple of screen shots, with and without virtual texturing:

    I'm using point filtering with clamped edges to illistrate the problem. Thanks.

  4. Well I found a solution. If I calculate the mip level of the page table texture and bias the texture coordinate like this before I sample from the page table it fixes the cracks. I just wonder why I need this...

    input.uv - (PageTableMipLevel+1.0)/VirtualTextureSize

  5. It's hard to say because you haven't posted all your code..

    It sure looks as if your derivatives are not constant across the surface though.

    When you use fract the difference between texture coordinates could be tiny on one texel, and huge for the next when it crosses between pages.

    If you use texture-arrays you might want to try using repeating texture wrapping and forget about the fract, that might work depending on how you set things up.

    Either that or use a texture sampler with scaled derivatives.


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