-
Notifications
You must be signed in to change notification settings - Fork 1
DemoGame: Rendering Blocks
On block registered:
- Load model asset and save it to a temporary map (keyed by asset path) (if it hasn't already been loaded)
On finalization of registry:
- Create model instance for each block type where the vertex texcoord data comes from the atlas the blocktype is registered to
- Store model instance verities and indices in block registry buffers
TODO List:
- How/When to create a descriptor set per block type? They need the pipeline that they are being made for. They also must have the same layout as the pipeline descriptor layout.
- pipeline needs the layout ahead of time
- How is the instance buffer filled? The player's view-projection matrix should always be local to the chunk they are in, but we want to avoid updating the instance buffer when a user moves to a different chunk.
The block registry holds a vertex and index buffer for all block type models. Each block type gets its own instance of its linked model asset. The texcoord data in the vertex of each block type model is based on the atlas int which the block type textures were stitched.
The world has 1 vertex buffer (at instance rate) for all rendered blocks. This holds the instance/model-matrix data for each block position in the world for all rendered chunks. This instance buffer is sorted by block type (there is an map of block type to index+count of instances), so that rendering each block type means just rendering a range in the instance buffer.
A couple of definitions:
- Chunk Render Distance (CRD) is the number of chunks which can render in a straight line, excluding the user's current chunk.
- Chunk Count is the number of chunks that should be loaded by around a player as
(2c+1)^3
, wherec
is the CRD (based on https://minecraft.gamepedia.com/Chunk#Player_ticket). - Chunk Side Length (CSL) is the number of blocks in length of each side of a chunk (default is currently 16 blocks). This means the total amount of blocks in a chunk is
s^3
wheres
is the CSL (4096 when CSL=16). - A model matrix (the only item in block instance data) is composed of 4 vector4 objects, each of which is 4 floats. That means a model matrix will have the size of
4^3
or 64 bytes (4 bytes per float * 4 floats per vector * 4 vectors).
Per https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkAllocateMemory.html,
Some platforms may have a limit on the maximum size of a single allocation. For example, certain systems may fail to create allocations with a size greater than or equal to 4GB. Such a limit is implementation-dependent, and if such a failure occurs then the error VK_ERROR_OUT_OF_DEVICE_MEMORY must be returned. This limit is advertised in VkPhysicalDeviceMaintenance3Properties::maxMemoryAllocationSize.
We can now determine the size of an instance buffer based on the CRD and compare it against the Vulkan regulations. The following examples are based on a CSL=16, and instance item of 64 bytes (1 model matrix).
- CRD = 5 (most likely example)
- Chunk Count =
(2*(CRD)+1)^3
= 1,331 - Chunk size (bytes) =
CSL*ModelMatrixSize
=16*64
= 262,144 bytes - Buffer Size (bytes) =
Chunk Count * Chunk Size
= 348,913,664 bytes
- Chunk Count =
- CRD = 7 (largest amount when restricted to 1GB of instance buffer memory)
- Buffer Size (bytes) =
Chunk Count * Chunk Size
= 884,736,000 bytes
- Buffer Size (bytes) =
- CRD = 11 (largest CRD when restricted to 4GB of instance buffer memory)
- Buffer Size (bytes) =
Chunk Count * Chunk Size
= 3,189,506,048 bytes
- Buffer Size (bytes) =