Megatexture Technology
Written sometime in July 2006
Doom 3 Megatexture technology is more a proof of concept than anything else.
- Any disk reads will stall the game loop.
- Create and render Megatextures up to 16384x16384.
What is known:
- Allows for one unique texture over the whole terrain.
- Artists can paint onto the terrain.
- The megatexture is a 32768x32768 texture.
- It is a 5461333333 byte (5.46 GB) texture that includes all mipmap levels.
- For generating the megatexture a few tileable textures are used.
File Format
Details on the MakeMegatexture command in Doom 3 / Quake 4.
- The megatexture is split into blocks of size 128x128.
- Only works for power of two source textures larger than 128^2. If a source texture for example is 32000x32000 the megatexture will be the exact size as a 16387x16387 megatexture.
File Header
The file header size is 12 bytes. Assuming little-endian representation.
struct MEGATEXTURE_HEADER { int32 tileSize int32 numBlocksX int32 numBlocksY };
Given a power of two size of the source texture we present the value of the header of the megatexture:
Source Texture Size | Header Value | Value of numBlocksX/Y |
64 | 80 00 00 00 00 00 00 00 00 00 00 00 | (invalid) |
128 | 80 00 00 00 01 00 00 00 01 00 00 00 | 1 |
256 | 80 00 00 00 02 00 00 00 02 00 00 00 | 2 |
512 | 80 00 00 00 04 00 00 00 04 00 00 00 | 4 |
1024 | 80 00 00 00 08 00 00 00 08 00 00 00 | 8 |
2048 | 80 00 00 00 10 00 00 00 10 00 00 00 | 16 |
4096 | 80 00 00 00 20 00 00 00 20 00 00 00 | 32 |
8192 | 80 00 00 00 40 00 00 00 40 00 00 00 | 64 | >
16000 | 80 00 00 00 40 00 00 00 40 00 00 00 | 64 |
16384 | 80 00 00 00 80 00 00 00 80 00 00 00 | 128 |
32000 | 80 00 00 00 80 00 00 00 80 00 00 00 | 128 |
32768 | Unable to load |
Padding
The actual texture data actually starts at 10000h regardless of the size of the megatexture. I can think of two purposes of the data between the header and the start of the texture data:
- Most likely it is simply padding allowing for the fastest possible streaming of texture data. A requirement for asynchronous IO (fastest read possible) is that the an offset into a file is at an offset which is a multiple of the harddisks sector size (usually 512).
- It's size is of 65524 (FFF4h) which can be thought of as a 255x255 grid which contains the type of terrain at each grid position. This must have been early research into how to keep information about the terrain type in the megatexture.
Texture Data
- Texture data is represented as RGBA (.TGA IS BGRA)
The preview screenshot the MakeMegatexture command creates is named
Let's take a look at the megatexture texture data give different source textures.
MakeMegatexture with 128x128 Source Texture
Texture data is between 20000h and 10000h and is exactly 65536 bytes. The megatexture simply holds the original texture ( 128x128x4 = 65536 ). There is no clipmap pyramid.MakeMegatexture with 256x256 Source Texture
Console output:
Writing 2 x 2 size 128 tiles to megaTextures/maptexture256.mega. writing to: I:\doom3\base\megaTextures\maptexture256.mega 1 blockRowsRemaining 0 blockRowsRemaining generating 1 x 1 block mip level row 0
I can confirm that it creates 4 128x128 blocks and one 128x128 mipmap.
MakeMegatexture with 512x512 Source Texture
Console output:
Writing 4 x 4 size 128 tiles to megaTextures/maptexture512.mega. writing to: I:\doom3\base\megaTextures\maptexture512.mega 3 blockRowsRemaining 2 blockRowsRemaining 1 blockRowsRemaining 0 blockRowsRemaining generating 2 x 2 block mip level row 0 row 1 generating 1 x 1 block mip level row 0
Based on what we've learned this creates:
- 4x4 128x128 blocks at finest clipmap level.
- 2x2 128x128 blocks at the finest + 1 clipmap level.
- 1x1 128x128 blocks at the coarsest clipmap level.
We can calculate the space this megatexture will need:
space = num blocks * 128^2 * 4 Bpp + 10000h = ( 16 + 4 + 1 ) * 128^2 * 4 Bpp + 10000h = 1 441 792 Bytes
This is the correct size.
MakeMegatexture with 32768x32768 Source Texture
256x256 blocks * 128^2 * 4 Bytes | 4294967296 |
128x128 blocks * 128^2 * 4 Bytes | 1073741824 |
64x64 blocks * 128^2 * 4 Bytes | 268435456 |
32x32 blocks * 128^2 * 4 Bytes | 67108864 |
16x16 blocks * 128^2 * 4 Bytes | 16777216 |
8x8 blocks * 128^2 * 4 Bytes | 4194304 |
4x4 blocks * 128^2 * 4 Bytes | 1048576 |
2x2 blocks * 128^2 * 4 Bytes | 524288 |
1x1 block * 128^2 * 4 Bytes | 262144 |
SUM: 5727059968 Bytes (5727 MB) |
Without an alpha channel the size becomes: 4295294976 Bytes (4295 MB).
Terrain Details
What is known:
- No geomorphing, JC prefers the simple brute force path.
- No LOD, brute force using efficient IB/VB's.
- Texture may stretch noticeably on steep cliffs, but can be slightly improved upon by texture coordinates adjustments.
Printing out the list of loaded images for a 8192x8192 megatexture we get:
-w-- -h-- filt -fmt-- wrap size --name------- 173:F 512 512 dflt RGB8 rept 1365k MEGA_maptexture8192.mega_0 174:F 512 512 dflt RGB8 rept 1365k MEGA_maptexture8192.mega_1 175:F 512 512 dflt RGB8 rept 1365k MEGA_maptexture8192.mega_2 176:F 512 512 dflt RGB8 rept 1365k MEGA_maptexture8192.mega_3 177:F 512 512 dflt RGB8 rept 1365k MEGA_maptexture8192.mega_4