Friday, June 25, 2010

Borders? Borders? I don't need no stinkin' borders (on disk)

Anyone who's read any paper about virtual texturing knows that you need to put borders around your pages, otherwise you get ugly seems because of bilinear interpolation.
This is because your page might be anywhere in your page texture, neighbouring other pages which have completely different colors, and when you sample an interpolated pixel near the border of the page, it interpolates between pixels of unrelated pages.

Usually the borders are build at preprocessing time, where the first 4 pixel horizontal or vertical lines are duplicated from a neighbouring page to serve as a border in the former page and visa versa.

Today I realized that the pages on disk don't need any borders at all, because you will always have all the information available to you to build those borders at upload time..

For example:

In this case, we've got a polygon crossing two pages, which are both visible, and both loaded from disk.
Here we can just copy the border pixels from both pages to the other one.


So what about this case?
Here we've got the same polygon crossing the same two pages, but one isn't loaded yet (or it's visible, in which case we really don't care), and we only have a lower resolution version of that page.
So what are we going to do now?
Well, we simply up-sample the lower resolution page, and then just copy border pixels from that page as before.

And when you think about it, this is actually more correct, because if we used a preprocessed border it would have been be a higher resolution border, and we'd actually get a (very subtle) seem here because the neighbouring page is different!

Bottom line:
  • Borders do not need to be stored, less disk space required.
  • The most correct resolution border is always in memory anyway.
  • Preprocessing is simplified.

Downsides:
  • More bookkeeping / work at runtime (but not much).
  • Borders of adjacent pages need to be updated when you load in a higher resolution page.

2 comments:

  1. I think, but I'm not sure, Andreas fixed this by implementing a custom bilinear filtering in the shader. From experience I would think, though, that it is more likely to have a negative performance impact. You may want to ask Andreas about it.

    Another train of thought: can you implement trilinear filtering in the same way by uploading the first mipmap level and using hardware trilinear (or even anisotropic) filtering. I think it may be a bit messy to get right, but it could be fast.

    ReplyDelete
  2. Doing bilinear filtering manually in a shader is much slower yes, that's why Crytek, Id software etc. use borders instead.

    As for the trilinear thing, yes I know about that, It's what Sean Barret did in his sparse virtual texturing demo in 2008 ;)
    (You are talking about uploading 2, instead of 1, mip map levels in the page cache, right?)

    ReplyDelete

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