Virtual texturing

Discussion in 'Rendering Technology and APIs' started by Infinisearch, Oct 19, 2011.

  1. Infinisearch

    Veteran Regular

    Joined:
    Jul 22, 2004
    Messages:
    739
    Likes Received:
    139
    Location:
    USA
    When implementing virtual texturing how do you determine which portion of the texture/s are currently visible? To be clear I mean how do I decide what to update the texture atlas with?

    Thanks in advance for any help.
     
  2. Rodéric

    Rodéric a.k.a. Ingenu
    Moderator Veteran

    Joined:
    Feb 6, 2002
    Messages:
    3,986
    Likes Received:
    846
    Location:
    Planet Earth.
    You render to a small framebuffer and jitter a little to catch things you might miss otherwise, then you read back from it to find out what you need.
    I'm pretty sure there are a number of presentations available out there detailing the process, AFAIR one even provides source code.
     
  3. sebbbi

    Veteran

    Joined:
    Nov 14, 2007
    Messages:
    2,924
    Likes Received:
    5,288
    Location:
    Helsinki, Finland
    Our virtual texturing system renders the scene to a 4x4 smaller 32 bit per pixel frame buffer. For this pass you do not need to calculate anything else than texture coordinates for each pixel and the mip level, so the pixel shader will be pretty simple (and very fast). Vertex shader input can be also really simple: position and (a rough precision) texture coordinate. Pass though the texture coordinate to pixel shader and transform the position.

    In the pixel shader, you can calculate the mip level either with gradient instructions (based on texture coordinate screen space derivatives) and a few math instructions, or you can use DX10/DX11 texture objects' CalculateLevelOfDetail-method (but that method needs DX10.1 hardware or better). Both methods are really fast.

    We directly transform the texture coordinates to page IDs in the pixel shader, as it saves a lot of CPU cycles (later in the pipeline), and makes it easier to quickly remove duplicate pages when the data is processed by the CPU. Our page ID is basically: 4 bit mip, 11 bit page Y, 11 bit page X (starting from most significant to least significant). The pixel shader outputs the packed page ID.

    Now on the CPU side, you will lock the texture data buffer (use staging resources on DX10/11). Each 32 bit value in the buffer represents one visible page. There's usually a lot of same page IDs in the locked buffer, so I recommend doing some quick and dirty duplicate removal before feeding that data to your cache (*). We are using LRU policy in our cache, and it has been working really well. In your cache design focus on query speed, since every visible page needs to be queried in every update (you do not want to load data that's already on cache). Adding and deleting pages can be slower operations, since the frequency of those operations isn't as high.

    (*) You can iterate the pixel buffer, and if "pixel = last added pixel" do not add it to visible array. This removes huge amount of duplicates already. On consoles it's very efficient to do duplicate check for whole cache tiles (it's very efficient since scanlines are not linear, but in tiled format, so a region of the image is in linear memory addresses). This kind of local duplicate check removes almost all duplicates with a very low cost.
     
  4. Infinisearch

    Veteran Regular

    Joined:
    Jul 22, 2004
    Messages:
    739
    Likes Received:
    139
    Location:
    USA
    Thank you both for your replies, they were very helpful.

    What exactly did you mean by jitter a little?
     
  5. MJP

    MJP
    Regular

    Joined:
    Feb 21, 2007
    Messages:
    566
    Likes Received:
    187
    Location:
    Irvine, CA
    Just to be clear here, nothing about virtual texturing explicitly requires you to render to a buffer and read it back to determine visible pages. You could certainly use other means to determine page visibility, in fact it's even possible to precompute (I believe the iPhone version of RAGE does this, someone correct me if I'm wrong).
     
  6. MJP

    MJP
    Regular

    Joined:
    Feb 21, 2007
    Messages:
    566
    Likes Received:
    187
    Location:
    Irvine, CA
    Every frame you can translate your projection a tiny bit (in XY space relative to the camera). This lets you pick up small details that might otherwise be missed due to rendering at a lower resolution.
     
  7. fuboi

    Newcomer

    Joined:
    Aug 6, 2011
    Messages:
    90
    Likes Received:
    46
    That's 26bits worth of bits: how efficient would it be to implement it as a logical OR into a 2^26 bitmap (8MByte) on PS3/360/PC? How well do different consoles and PC GPU generations support integer boolean operations?

    Reducing mip resolution down to 2 bits looks like a reasonable optimization for that case , to get down to 2MByte. Is there a point in managing mips with such a fine granularity? I can only think of the very reduced memory on consoles. Looks to me that paging 16 mip levels (some of them tiny) is over managing the problem.

    22 bits for page number are 4 million unique pages, possibly postprocessing the final content to linear 1D page numbers could lead to further address bits reductions, reducing pagehit bitmap memory footprint below 1Mbyte.
     
  8. Infinisearch

    Veteran Regular

    Joined:
    Jul 22, 2004
    Messages:
    739
    Likes Received:
    139
    Location:
    USA
    Such as...?
     
  9. frogblast

    Newcomer

    Joined:
    Apr 1, 2008
    Messages:
    79
    Likes Received:
    4
    The viewer's distance from an object, or even a fully precomputed solution based on viewer position. Something that doesn't depend on feedback wouldn't suffer from any blurry mess when the viewer suddenly turns 180. It also would enable you to prefetch textures for an object that will suddenly fill the user's view, even if it isn't there yet. (wouldn't want your Imp dropping out of a monster closet to appear covered in all of 2x2 pixels).
     
  10. MJP

    MJP
    Regular

    Joined:
    Feb 21, 2007
    Messages:
    566
    Likes Received:
    187
    Location:
    Irvine, CA
    Visibility in real-time graphics has a long history of research. Most of it was for the purpose of hidden surface removal, but it's almost the exact same problem (instead of trying to figure out which polygons or objects are visible, you want to figure out which texture pages are visible). So you can rasterize on the GPU and feed back to the CPU, or you can rasterize on the GPU and have the GPU figure out which pages need to be loaded in, or you can rasterize completely on the CPU, you can use PVS, you can use portals/antiportals, you can use bounding volume hierarchies, you can ray-trace, you can use occlusion queries, etc. Or you can even do something really simple like what they did in Quake Wars, which is they just loaded in terrain pages in a concentric ring around the camera.
     
  11. Infinisearch

    Veteran Regular

    Joined:
    Jul 22, 2004
    Messages:
    739
    Likes Received:
    139
    Location:
    USA
    Sorry to bump an old topic but I have a stupid question... In software based virtual texture mapping triangle (UV's) can't cross tile boundaries right? At least if you're using texture filtering. The texturing unit would potentially fetch the wrong data correct?
     
Loading...

Share This Page

  • About Us

    Beyond3D has been around for over a decade and prides itself on being the best place on the web for in-depth, technically-driven discussion and analysis of 3D graphics hardware. If you love pixels and transistors, you've come to the right place!

    Beyond3D is proudly published by GPU Tools Ltd.
Loading...