Holger DammertzSome personal notes I made during my demo implementation of Sparse Virtual Texturing using OpenGL.
On this web-page you can find some personal notes made during programming a sparse virtual texturing demo in my spare time. The demo was developed in C++ using OpenGL. The video below shows the current state. My intend is to update (see the <Change Log>) this page from time to time when I try out new things regarding virtual texturing and also to have this page as a resource of references to the many other works regarding virtual texturing (see Section <Other Work on Virtual Texturing>)
Some details for the video above:
Virtual Texture Resolution: 32256x32256 pixels
Render Resolution: 960x540
Features: Tri-Linear filtering, async tile loading, CPU readback for tile determination
Tile Size: 128x128 (126 + 2 pixel border for filtering)
Performance: ~1.6ms per frame on a GeForce 660Ti (no serious optimizations done so far)
Sparse virtual texturing is a technique that allows real time rendering of textures that are too large to fit into video memory. This is achieved by only loading individual tiles of the texture that are needed for the current view into memory and keeping the rest on disc. The name virtual refers to the technique of virtual memory used in memory management systems of operating systems. In its application it is basically an out of core technique for real time texture rendering. It's promises are unique high resolution texture detail for large scenes in real time and this technique was made recently popular by the implementation in the id-software game Rage.
The fundamental idea of virtual texturing is quite old and by now is very well documented and researched in several different resources. The basic idea was described in a talk in 1999 by Hall (3Dlabs) [hall99]. Probably the first publicly available (software) implementation was given by Sean Barret in 2008 [barret08] where he presented Sparse Virtual Textures at GDC and much of the following work build on his presentation and implementation. Mittring gave a talk on Advanced Virtual Texturing topics [mittring08] at Siggraph 2008. In this talk he discusses among other things the precision problems regarding tile access, how the indirection texture can be handled, mip-map generation and mesh parameterization for content generation. In a talk at Siggraph 2009 [waveren09] van Waveren describes several details regarding their implementation for the id Software title Rage. In 2010 he and Evan Hart gave a talk together at GTC on Virtual Texturing [waveren10] where they talk about some details of parallel variable bit rate decompression of texture tiles.
A very detailed resource on virtual texturing is the 2010 Master Thesis by Mayer [mayer10] that summarizes many aspects and gives several details on implementation challenges and solutions. Building partly on this work the Master Thesis of Andersson and Göransson [andersson12] presents and analyzes an implementation of virtual texturing in WebGL.
An optimization using CUDA regarding tile determination on the GPU is presented in [hollemeersch10]. Their work could be directly adapted for an implementation in OpenCL or in an OpenGL Compute shader.
At GDC 2010 Sugden and Iwanicki presented a system [sugden11] they called Mega Meshes. It is a full solution of content production tools and rendering technology to build huge seamless worlds with a hierarchical geometry representation that can be streamed and unique texturing on this geometry (+ some real time global illumination lighting). The texturing uses an implementation of Virtual Texturing and the talk gives several insights into practical problems and solutions. They also discuss compression techniques for tiles of different channels (albedo, normal) in some detail.
At Siggraph 2012 a course [sig12vtCourse] was given. Besides a general introduction to virtual texturing the course also contains a talk on the new AMD OpenGL extension of Partially Resident Textures (AMD_sparse_texture).
An interesting part of a demo implementation of virtual texturing is how to create reasonable test data without developing specific tools (and having access to artists who use them). Available scenes are usually textured using classical mapping of many (often repeated) textures for the whole scene. While it is possible to convert such scenes into a single large Virtual Texture as was for example done in the PC game Brink (see the Blog entry by Hollemeersch). These scenes are also often designed so that all textures fit into GPU memory. Using a large height mapped terrain is not a very good option either for testing a virtual texturing implementation because than the uv-mapping becomes trivial and using a clip-map would be a better solution.
For my test I chose to create a simple uniquely textured scene by unwrapping a large mesh and baking a procedural surface texture plus some simple lighting directly into the virtual texture using blender. Even though this approach is conceptually very simple the actual details are still a lot of work to get to acceptable quality. I probably spend more time experimenting with automatic uv-unwrapping and light map baking artifacts than writing the virtual texturing code.
These two images show the geometry of the scene and the UV-Layout used for the virtual texture. You can see many small and very small individual islands in the top and the right
of the UV-Layout. This results in some artifacts visible during rendering (and a lot of sub-optimal page requests) but was the best I could achieve so far with automatic unwrapping in blender for this scene.
The most important/interesting steps I performed to create the test data
If you want to create the data on your own, you can download the .blend file here (tested with blender 2.64a). It contains the mesh, procedural texture, and lighting setup and a python script that creates all the texture data. The script is set up to create the 64512x64512 pixel virtual texture (tiled to 4032x4032 pixels) at all mip-levels down to a single tile of 126x126 pixel. The images are for a tile resolution of 128x128 (126 + 1 pixel border on all sides). The result are 346 4k .tga images with a total of 7.12GB. All settings are hardcoded at the beginning of the script.
[barret08] Sparse Virtual Textures, Sean Barret, 2008
[waveren09] id Tech 5 Challenges - From Texture Virtualization to Massive Parallelization, J.M.P. van Waveren, 2009
[waveren10] Using Virtual Texturing to Handle Massive Texture Data, J.M.P. van Waveren and Evan Hart, 2010, NVIDIA GTC 2010
[hall99] Virtual Textures - Texture Management in Silicon, Chris Hall (3DLabs Inc.), 1999
[mayer10] Virtual Texturing, Albert Julian Mayer, 2010, Master's Thesis at Technische Universität Wien
[sugden11] Mega Meshes, Ben Sugden and Michal Iwanicki, 2011, GDC 2011
[andersson12] Virtual Texturing with WebGL, Sven Andersson and Jhonny Göransson, 2012, Master's Thesis at Chalmers University of Technology
[hollemeersch10] Accelerating Virtual Texturing Using CUDA, Charles-Frederik Hollemeersch, Bart Pieters, Peter Lambert, and Rik Van de Walle , 2010, GPU Pro: Advanced Rendering Techniques
[sig12vtCourse] Virtual texturing in software and hardware, Juraj Obert, J.M.P. van Waveren, Graham Sellers, 2012, ACM SIGGRAPH 2012 Courses
[mittring08] Advanced Virtual Texture Topics, Martin Mittring, 2008, ACM SIGGRAPH 2008 Courses, Advances in Real-Time Rendering in 3D Graphics and Games