# The Sad State of Hardware Virtual Textures

Antoine Richermoz, Fabrice Neyret

► To cite this version:

Antoine Richermoz, Fabrice Neyret. The Sad State of Hardware Virtual Textures. UGA - Université Grenoble Alpes; INRIA Grenoble - Rhône-Alpes. 2025, pp.13. hal-05138369

HAL Id: hal-05138369

https://hal.science/hal-05138369v1

Submitted on 1 Jul 2025

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution 4.0 International License
# The Sad State of Hardware Virtual Textures

Antoine Richermoz

INRIA, LJK, UGA

Fabrice Neyret

INRIA, LJK, CNRS

<figure><img src="image_2.png" /></figure>

<figure><img src="image_3.png" /><figcaption>**Figure 1.** *Left:* Virtual texturing splits textures into tiles. A tile map associates virtual tiles in UV space to physical tiles in a texture atlas. *Right:* Hardware virtual textures outperform software virtual textures in sampling speed, but surprisingly they totally underperform in tile binding speed (qualitative graph, see section 4 for details).</figcaption></figure>

## Abstract

Virtual textures (also known as sparse textures, tiled textures, partially resident textures, or MegaTextures) decouple texture space from memory space, allowing for a more efficient use of GPU memory by leveraging sparse compression and on-demand texture streaming. This is of particular interest for texturing giant terrain meshes and storing sparse voxel geometry in volumetric textures. Virtual textures can be implemented in software, but doing so is cumbersome and makes them expensive to sample. GPU vendors and graphic APIs have support for virtual textures in hardware, but the current implementation suffers from severe and sometime strange limitations. In this article, we re-explain the ideas and motivations behind virtual textures, we give an overview of how they can be implemented in software, we explain the limitations of current hardware virtual textures, and we compare the texture sampling and tile binding performances of software and hardware virtual textures under different GPUs and drivers. Our goal is to motivate hardware vendors and driver writers to update hardware virtual texture support to make it truly useful.
# 1. The need for virtualization in textures

Textures are a fundamental building block of computer graphics. They are used to describe continuously varying features (fields), over 2D or 3D space. They consist of a grid of values, which can be sampled at fractional coordinates using linear interpolation, and with footprints using mipmapping and anisotropic filtering.

Memory for regular textures is allocated in an all or nothing way. This is suboptimal as textures are often partially hidden or partially empty. Partial visibility can be caused by being partially out of the view frustum or partially occluded. Even if part of a texture is visible, it might be far away from the camera and thus not need to be in the highest resolution. Such is often the case for terrain textures (Figure 2, left). Partially empty textures are mainly used for 3D voxel textures representing solid geometry, as they mostly consist of empty space in between objects (Figure 2, right).

Allocating memory to store hidden or empty parts of a texture is a big waste. To avoid this, virtual textures are allocated on a tile basis. That way, empty or hidden tiles do not need to allocate memory at all, and memory is only being consumed to store actually useful texels. This even enables virtual textures to be larger (in terms of virtual texels) than memory constraints would otherwise allow. For example, Rage [Obert et al. 2012] used a single $128k \times 128k$ virtual texture to cover its entire world. This texture would require 64GB of memory if it were a regular texture (very optimistically supposing 4 bytes per texel), yet it was able to run on a PS3 with a meager 256MB of VRAM (I did not say it ran without issue, but it ran).

<figure><img src="image_4.png" /><figcaption>**Figure 2.** Left: Partially visible terrain texture. A) Visible area where high resolution is needed. B) Visible area where low resolution is sufficient. C) Area hidden by being out of the view frustum. D) Area hidden by being occluded. Right: Partially empty (sparse) volumetric texture. Non empty voxels are in blue and empty voxels are in red.</figcaption></figure>
In the rest of this we article, we start by showing how virtual textures can be imple-
mented in software in Section 2, then we explain the history and limitations of current
hardware virtual textures in Section 3, and finally we measure the performances of
hardware virtual textures across multiple GPU vendors and drivers and compare them
the to software virtual textures in Section 4.

## 2. Software virtual textures

2.1. Basic texel fetching

Virtual textures can be implemented in software using two components : a regular texture that serves as an atlas for tiles, and a tile map that associates virtual tiles in UV space to physical tiles in the atlas (see Figure 1 Left). This section shows examples of a typical software virtual texture implementation, written in GLSL. In these examples, the tile map is implemented using a regular texture, see Section 2.3 for more details on possible tile map implementations.

Software virtual textures can be fetched by first computing the virtual tile that
contains the pixel of interest, querying the tile map to find the physical tile that corre-
sponds to that virtual tile, then fetching the pixel data from the atlas.

vec4 texelFetchVirtualTexture(ivec2 p) {
    ivec2 virtualTile = ivec2(p / tileSize);
    ivec2 physicalTile = texelFetch tileMap, virtualTile, 0).xy;
    ivec2 atlasP = physicalTile * tileSize + p % tileSize;
    return texelFetch(atlas, atlasP, 0);
}

<caption>**Listing 1.** Software virtual texture texel fetching</caption>

Virtual textures can be multilevel (mipmapped) by adding the mip level as an addi-
tional component to the virtual tile address. Tiles are always the same size regardless
of their mip level, and the atlas itself does not need to be mipmapped (though it can
be for m

vec4 texelFetchLodVirtualTexture(ivec2 p, int lod) {
    ivec2 virtualTile = ivec2(p / tileSize);
    ivec2 physicalTile = texelFetch tileMap, virtualTile, lod).xy;
    ivec2 atlasP = physicalTile * tileSize + p % tileSize;
    return texelFetch(atlas, atlasP, 0);
}

<caption>**Listing 2.** Software virtual texture texel fetching with lod</caption>
## 2.2. Texture filtering

Algorithms 1 and 2 works for non-filtered textures, but some might say that the whole point of textures is their ability to be smoothly filtered. Unfortunately, this is where software virtual textures starts to become much less elegant.

**Bilinear filtering** Bilinear filtering inside a tile isn't an issue, we can just rely on hardware interpolation. But when sampling at the frontier between tiles, texels that are neighbors in virtual space have no reason to be neighbors in atlas space, and so hardware interpolation would not interpolate the correct texels. This can be solved in three ways: manual interpolation, stochastic interpolation, and tile borders.

* Manual interpolation doubles texture sampling cost when sampling tile edges (or even quadruples on corners, and octuples on 3D textures corners).

* Stochastic interpolation randomly samples only one of the touched tiles, with a probability distribution based on the interpolation coefficients. With a good temporal accumulation (TAA) solution it converges to the correct interpolated value, but it may make tile edges shimmer.

* Tile borders add a small border on the edges of each atlas tile (see Figure 3) to allow hardware interpolation to work. Border texels are copied from the corresponding virtual neighbor tile, which means that one has to issue multiple writes for edge texels when updating a texture. Tile borders introduce a memory overhead, calculations for which are available at the end of this section. Algorithm 3 shows how to sample a software virtual texture with double tile borders.

<figure><img src="image_5.png" /><figcaption>**Figure 3.** Illustration of tile borders. Tiles are padded with a border containing copies of the neighboring tiles texels to permit correct hardware texture filtering. Borders can be on all sides (double border, *Right*), or only half of the sides (single border, *Center*) on some cases.</figcaption></figure>
```cpp
vec4 textureSampleVirtualTexture(vec2 uv, int lod) {
    vec2 p = uv * (virtualTextureSize >> lod);
    ivec2 virtualTile = ivec2(p / tileSize);
    ivec2 physicalTile = texelFetch tileMap, virtualTile, lod).xy;
    vec2 atlasP = physicalTile * (tileSize + tileBorder * 2) +
        mod(p, tileSize) + tileBorder;
    vec2 atlasUV = atlasP / textureSize(atlas, 0);
    return texture(atlas, atlasUV);
}
```

<caption>**Listing 3.** Software virtual texture sampling with borders</caption>

**Mipmap filtering** Mipmap filtering can be implemented using the same three techniques. Manual and stochastic interpolation work in the exact same way as for bilinear interpolation. The equivalent to tile borders for mipmapping means adding one mip level to the atlas to give each tile its own little miped version, with texels copied from the corresponding virtual mipmap neighbor tile. Algorithm 4 shows how to sample a virtual texture with mipmap borders.

```cpp
vec4 textureSampleLodVirtualTexture(vec2 uv, float lodf) {
    int lod = int(lodf);
    vec2 p = uv * (virtualTextureSize >> lod);
    ivec2 virtualTile = ivec2(p / tileSize);
    ivec2 physicalTile = texelFetch tileMap, virtualTile, lod).xy;
    vec2 atlasP = physicalTile * (tileSize + tileBorder * 2) +
        mod(p, tileSize) + tileBorder;
    vec2 atlasUV = atlasP / textureSize(atlas, 0);
    return textureLod(atlas, atlasUV, fract(lodf));
}
```

<caption>**Listing 4.** Software virtual texture sampling with mipmap borders</caption>

**Anisotropic filtering** Anisotropic filtering can also be implemented using the same three techniques. But for tile borders it has the additional caveat that hardware computed gradients will be based on the atlas UVs, and so will be incorrect on tile edges. This can be solved by computing them manually using the virtual UVs and $dFdx / dFdy$ along with *textureGrad* to sample the atlas. Algorithm 5 shows how to sample a virtual texture with hardware anisotropic filtering when using tile borders. In this algorithm we use *textureQueryLod* to get the appropriate virtual mip level to sample. If this is not available, you can use the solution given in [Pema] to compute it manually.
```cpp
vec4 textureSampleAnisoVirtualTexture(vec2 uv) {
    float lodf = textureQueryLod(regularTex, uv).x;
    int lod = int(lodf);
    vec2 p = uv * (virtualTextureSize >> lod);
    izec2 virtualTile = izec2(p / tileSize);
    izec2 physicalTile = texelFetch tileMap, virtualTile, lod).xy;
    vec2 atlasP = physicalTile * (tileSize + tileBorder * 2) +
        mod(p, tileSize) + tileBorder;
    vec2 atlasUV = atlasP / textureSize(atlas, 0);
    vec2 gradScale = vec2(virtualTextureSize >> lod) /
        textureSize(atlas, 0);
    return textureGrad(atlas,
        atlasUV, dFdx(uv) * gradScale, dFdy(uv) * gradScale);
}
```

<caption>**Listing 5.** Software virtual texture sampling with hardware anisotropic filtering</caption>

**Border memory overhead** The width of borders and the amount of memory overhead it introduces depends on what filtering features you want your virtual texture to support. For basic bilinear filtering a single side 1 texel wide border can be sufficient, but you need to make sure to use corner texel sampling (or offset UVs by half a texel to make center texel sampling behave like corner sampling). Using mipmap borders forces tile size and border width to be even numbers. Hardware anisotropic filtering requires double side borders with a width equal to the maximum anisotropic filtering value you want to allow for. The formula below gives the total overhead.

* $o$: The memory overhead
* $d$: The texture dimensionality
* $t$: The virtual tile width
* $s$: 1 for single border, 2 for double border (Fig 3)
* $a$: The maximum anisotropic filtering value
* $m$: 1 if mipmap borders are used, 0 otherwise

For a 2D 128×128 virtual tile size this amounts to the following border overheads:

<table><tr><td>No anisotropic filtering and mipmap border disabled</td><td>1.6%</td></tr><tr><td>No anisotropic filtering and mipmap border enabled</td><td>29%</td></tr><tr><td>4X anisotropic filtering and mipmap border disabled</td><td>13%</td></tr><tr><td>8X anisotropic filtering and mipmap border disabled</td><td>27%</td></tr><tr><td>16X anisotropic filtering and mipmap border disabled</td><td>56%</td></tr><tr><td>16X anisotropic filtering and mipmap border enabled</td><td>95%</td></tr></table>

To limit the tile border memory overhead, UnrealEngine chooses to use stochastic interpolation for mipmap filtering and limits anisotropic filtering to 4X by default [UnrealEngine].
## 2.3. Data structures

**Atlas texture** The atlas texture is a big regular texture with a size that is a multiple of the physical tile size (= virtual tile size + border), with zero or one mipmap level (depending on the m filtering strategy used, see Section 2.2).

**Tile map** The tile map can be implemented in a multitude of ways. First, it can have different topologies: direct tables are fast but quickly consume memory, trees are compact but take time to traverse, hash tables can be the best of both worlds provided you have an adequate hash function. Second, it can use different types of GPU resources. Sampled textures used with *texelFetch* are the traditional choice. They have the advantage of being available on all platforms. They can also benefit from z-curve ordering for better locality. But since z curve ordering is a hardware dependent vendor secret, it is not specified or exposed to the user, which prevents you from directly mapping textures to the CPU. Sampled textures also have the drawback of using the texture unit, data bus, and cache as the atlas texture accesses, limiting the total potential bandwidth (although this might not be the case when using *texelFetch*, depending on the specific hardware). Storage images used with *imageLoad* should be broadly similar to sampled texture used with *texelFetch*. Storage buffers allow for more flexibility in the data types. Uniform buffers are limited on Nvidia hardware to 64k bytes, and are almost identical to storage buffers on other vendors.

# 3. Hardware virtual textures

## 3.1. History

To make virtual texturing more efficient (and to make graphics developers lives easier), GPU vendors started in the 2010's to add support for hardware virtual textures [Obert et al. 2012; NvidiaMaxwell]. With hardware virtual textures, the tile map is entirely managed by the GPU driver. Since the texture unit is now aware of the in-direction scheme, it can correctly interpolate texels across different tiles. This makes the shader code for accessing hardware virtual textures the exact same as for regular textures, making their use transparent to shader writers. Hardware virtual texture tile binding (mapping from virtual tiles to physical tiles) is managed through calls to the graphics API. Hardware virtual textures have enjoyed great vendor support, being available on all GPUs from Nvidia, AMD (including modern PlayStation and Xbox consoles), Intel, Apple, and even some mobile GPU vendors [GPUinfo]. They can also be accessed through all major graphics APIs: OpenGL, Vulkan, DirectX 11 and 12, Apple Metal, GNM (the PlayStation API), and CUDA. The only big missing actors are WebGL and WebGPU, although this is being discussed [WebGPU].
## 3.2. Limitations

Unfortunately the current implementations of hardware virtual textures suffer from severe and sometimes strange limitations, making them much less used than they could be. These limitations are listed below, ordered from most to least critical.

**Texture size** One of the main points of virtual texturing is the ability to create giant textures. Unfortunately current hardware virtual textures cannot be larger than regular textures. This limits them to just $32k^2$ pixels and $16k^3$ voxels on Nvidia, $16k^2$ and $8k^3$ on AMD, and $16k^2$ and $2k^3$ on Intel [GPUinfo]. (Interestingly, 2D textures can go up to $128k \times 64k$ in CUDA if you disable textureGather functionality [CUDA]).

**Tile binding performance** Hardware virtual texture tile binding is managed by the GPU driver through graphics API calls. Unfortunately those calls can be very slow, up to 100 ms to bind 1000 tiles, making it unsuitable for real time updating of textures. This varies greatly depending on GPU vendors and drivers. In the best cases the performance is actually good enough for real time tile binding, but the uncertainty makes it unappealing to developers. Detailed analysis of hardware virtual textures binding performances can be seen in Section 4.2.

**Tile status** When using virtual textures, it is useful to be able to query the state of tiles (bound, unbound) from shader code. The current implementations can already return a bitfield containing tile status information. Unfortunately, this bitfield only contains the boolean information telling whether all the tiles touched by a texture access footprint are bounded or not [GLSL; HLSL; MSL]. This is useful, but it's a shame not to take advantage of this bitfield to return more information, such as indicating precisely which tiles touched by the texture access were bound, or knowing the lowest bounded mip level for a particular UV.

**Anisotropic filtering support** Nvidia supports up to full 16X anisotropic filtering for hardware sparse textures, but Intel only supports up to 4X and AMD none at all. We did not find the information for other vendors.

**GPU side tile binding** Hardware virtual texture tile binding can only be changed through CPU API calls. In today's and tomorrow's GPU driven pipelines, this is a limitation. For applications that want to update the tile binding each frame, this forces you to do costly CPU-GPU synchronizations, limiting the utilization of both. Allowing for tile binding to be managed from the GPU would allow for much more advanced virtual texture systems, as showed in GigaVoxels DP [Richermoz and Neyret 2024].

**Low level API** In the current hardware virtual texture API, the tile map is managed by the driver. This is convenient for beginners, but limiting for advanced users. Moreover
this is the root cause of the unreliable performance of hardware virtual textures. In the zeitgeist of our time of giving users more low level access to the GPU, a new virtual texture API could leave tile map management to the user. Instead of taking texture coordinates in virtual space, the texture sampling functions of this new API would take a list of tile indices in the tile atlas, along with a texture coordinate that is local to that set of tiles.

**Fixed tile sizes** All hardware virtual textures implementations use the same standardized tile sizes [StandardTileSizes]. These standardized tile sizes are designed to be always 64KB, regardless of their dimensionality or texel format. The standardization make it easier to develop cross vendor applications, and the homogeneity in memory size has the benefit of allowing for tiles with different texture formats to share the same pool. However it has the drawback of causing some tile sizes to not be perfect squares / cubes, and more generally the fixed tile sizes may be seen as restrictive.

## 4. Performance comparison

In this section, we compare the texture sampling (4.1) and tile binding (4.2) performance of software and hardware sparse textures across the different GPU vendors and drivers. For the sake of simplicity, only Vulkan was tested. The list of tested GPUs and drivers can be seen in Table 1. The different GPUs are all accompanied by an AMD Ryzen 9 7900X processor, running under Arch Linux with kernel 6.12 or Windows 11. Source code for the test program used to generate these results is available at https://gitlab.com/rcmz/sparsetexturestests.

<table><caption>**Table 1.** List of tested GPUs and drivers</caption><thead><tr><th></th><th>Vendor</th><th>AMD</th><th>Nvidia</th><th>Intel</th></tr></thead><tbody><tr><td></td><td>GPU</td><td>RX 6800</td><td>RTX 4080</td><td>ARC A770</td></tr><tr><th rowspan="4">Driver</th><th>Windows</th><td>AMD Windows</td><td>Nvidia Windows</td><td>Intel Windows</td></tr><tr><th>Linux Closed Source</th><td>AMDGPUPRO</td><td>Nvidia Linux</td><td></td></tr><tr><th>Linux Open Source</th><td>AMDVLK</td><td></td><td></td></tr><tr><th>Linux Mesa</th><td>RADV</td><td>NVK</td><td>ANV</td></tr></tbody></table>
<figure><img src="image_6.png" /><figcaption>**Figure 4.** Scene used to benchmark sampling performance. It consists of a 512³ mipmapped virtual texture filled with an FBM Perlin noise. Left: Front view, Right: Side view</figcaption></figure>

## 4.1. Texture sampling

The objective of this test is to measure the relative sampling performance of regular, software virtual, and hardware virtual textures. The goal is not to compare the absolute performances between vendors or drivers, as it mostly depends on the specific cards used.

The benchmark consists of a ray marcher going through a 512³ mipmapped virtual texture filled with a semitransparent FBM Perlin noise (see Figure 4). No shading is done, so this test really stresses raw texture sampling performance. A bounding box test is done before sampling so out of bound sampling performance is not tested. The camera rotates around the texture volume in order for the rays to traverse the volume from all directions. The texture tiles are fully bounded, with a random virtual to physical tile mapping. All tests were done at a resolution of 1024 x 1024.

The implementation choices for the software virtual texture are the following. Virtual tiles of size 32 x 32 x 16 (same as the standardized hardware virtual texture tiles for 32bit texels), with a single side border of 1 texel (so physical tiles of size 33 x 33 x 17). A direct table using a storage buffer for the tile map. And a linearly interpolated texture with no mipmap for the tile atlas, mipmap interpolation being done manually. These might not be the best choices for all platforms, but are in our opinion a good tradeoff in terms of speed, memory usage, and complexity.

Results can be seen in Chart 5. The first conclusion that we draw from this data is that drivers can have a huge influence on performances! Even on this extremely simple test. The second conclusion is that hardware sparse textures perform almost as good as regular textures on most drivers. The third conclusion is that software sparse textures perform about 50% of hardware sparse textures (and therefore also
<figure><img src="image_7.png" /><figcaption>**Figure 5.** Texture sampling performance of regular, hardware virtual, and software virtual textures under different GPU drivers. (In frame per second, higher is better)</figcaption></figure>

about 50% percent of regular textures). Of course this is only a very general rule of thumb, as very much depends on the particularities of the sparse texture implementation (tile map structure, edge interpolation, mipmap interpolation), and better results can probably be achieved. Still, it shows that when it comes to texture sampling, having virtual textures managed at the hardware level makes a huge difference. And it also shows that hardware virtual textures make the sampling overhead compared to regular textures acceptable.

## 4.2. Tile binding

The goal of this test is to measure the absolute performance of tile binding updates for hardware and software virtual textures. For hardware virtual textures, the tile binding updates are entirely handled by the driver. For software virtual textures, updating the tile binding just means issuing a single write to array in GPU memory (because we use a direct table for the tile map).

The test measures the average time it takes to bind 1024 tiles. Batches of 936 tiles are successively bound to the virtual texture using a random mapping. Those mapping are random but non overlapping, meaning that no two binding call share the same virtual tile position or physical tile slot. Ten of those batches are needed to fully bind the texture, then a new set of bindings is generated and the process is repeated three times.

Results are shown in Chart 6. This test shows the huge disparity in hardware binding performance between the different drivers, almost a 300X difference between the fastest and the slowest! We can see that while NVK and Intel drivers provide binding performances compatible with real time performances, the other drivers do not. This probably explains why game developers don't want to use hardware virtual textures
<figure><img src="image_8.png" /><figcaption>**Figure 6.** Tile binding performance of hardware virtual and software virtual textures under different GPU drivers. (In millisecond, lower is better, logarithmic scale)</figcaption></figure>

for video games. The Nvidia and AMD Windows drivers (the two most important drivers for PC gaming), while not being the worst, are not performant enough to be commercially usable. Such disparity in performances is honestly hard to explain. The main factor is probably differences in data structures used for the tile map, and perhaps inefficiencies caused by calls to the OS kernel that can required to manage GPU memory. The differences between different drivers for the same card shows that this is a driver software issue and not a hardware one.

Software binding performance is very consistent across drivers and better than any hardware binding result. This explains why software virtual textures are still the preferred choice for most developers today. We can also see that the Intel Linux hardware texture binding is probably near optimal, as it is very close to software virtual texture bind times.

**5. Conclusion**

Virtual textures expands the concept of textures to make it drastically more memory efficient in situations of partial visibility or sparse content. There seems to be a sizable and growing interest from graphics programmers to employ them. Unfortunately, virtual textures are stuck in a weird conundrum. Software virtual textures are cumbersome to use, have poor sampling performances, and induce a memory overhead. Hardware virtual textures promised to fix those issues, but are made unusable by limited texture size, and terrible binding performance on most drivers. Still, Intel and NVK shows that hardware virtual texture binding can be done efficiently, so let's hope that we are only one Nvidia and AMD driver update away from usable hardware virtual textures across all GPUs.
## References

* CUDA Programing Guide Features and Technical specifications. URL: https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#features-and-technical-specifications. 8

* GLSL extension for sparse textures sampling. URL: https://registry.khronos.org/OpenGL/extensions/ARB/ARB_sparse texture2.txt. 8

* GPUinfo Vulkan Database. URL: https://vulkan.gpuinfo.org. 7, 8

* HLSL specification for tiled textures sampling. URL: https://learn.microsoft.com/en-us/windows/win32/direct3d11/hlsl-tiled-resources-exposure. 8

* MSL specification for sparse textures sampling. URL: https://developer.apple.com/documentation/metal/reading-and-writing-to-sparse-textures. 8

* Nvidia Maxwell GeForce GTX 980 Whitepaper. URL: https://www.ece.lsu.edu/gp/refs/GeForce-GTX-980-Whitepaper-FINAL.pdf. 7

* OBERT, J., VAN WAVEREN, J. M. P., AND SELLERS, G. Virtual texturing in software and hardware. In ACM SIGGRAPH 2012 Courses, 2012. ISBN 9781450316781. URL: https://doi.org/10.1145/2343483.2343488. 2, 7

* Pema reverse engineering mipmap selection form UV gradients. URL: https://pema.dev/2025/05/09/mipmaps-too-much-detail. 5

* RICHERMOZ, A. AND NEYRET, F. Gigavoxels dp: Starvation-less render and production for large and detailed volumetric worlds walkthrough. Proc. ACM Comput. Graph. Interact. Tech., 2024. URL: https://doi.org/10.1145/3675389. 8

* Standart tile size for Vulkan sparse images. URL: https://docs.vulkan.org/spec/latest/chapters/sparsemem.html#sparsememory-standard-shapes. 9

* Unreal Engine documentation streaming virtual texturing. URL: https://dev.epicgames.com/documentation/en-us/unreal-engine/streaming-virtual-texturing-in-unreal-engine#limitations. 6

* WebGPU discussion on support for sparse textures. URL: https://github.com/gpuweb/gpuweb/issues/455. 7