2
\$\begingroup\$

I decided on using 16x16x16 (4096 total) chunks of blocks.

Problem is with textures. First idea was about texture atlas but it would require a lot of calculation and possible problems in dividing UV (1) by atlas size (power of 2). Then I was thinking about using array of textures or sampler2darray.

I do not have fixed amount of textures and I reserved uint16 (65,535) for block-only textures (those textures are not used anywhere else, even items have their own item-only textures). All those textures are loaded before the world (based on loaded "mods").

I got so far that array of textures should be best solution because they support different resolutions (8x8, 16x16, 32x32, 64x64...) without duplicated pixels (which sampler2darray would require when even 1 texture has higher resolution because all textures would be re-scaled to fit it).

Problems I found with array of textures are:

  • the length must also be defined in shader (which I would need to recompile at runtime)
  • limited length (256 to 2048 based on vulkan.gpuinfo.org but even Minecraft has 229 block types, some with multiple textures)

Advantages are:

Which type of storage for textures is best in this case?

Or should I separate faces by textures, create VkPipeline for each texture and render them one by one?

EDIT: Each block has at least 1 texture (most time unique) but can be higher then 6 (different texture for each face) when 1 block is made of multiple cubes = non-solid.

\$\endgroup\$
6
  • \$\begingroup\$ I'm not sure why you'd have problems with textures in a minecraft-line world. I'm not sure if I understand you correctly, but you don't need to create a separate texture for each cube, if all cubes are "earth" cubes for example, they should share the same one. That means 1 texture for multiple cubes. \$\endgroup\$ Dec 19, 2018 at 10:54
  • \$\begingroup\$ @TomTsagk Yes but Minecraft has 229 unique block types (I edited "blocks" to "block types"), with mods it can easily go to 1,000. I want it to be capable of those (not limited to only few). \$\endgroup\$
    – Abit Gray
    Dec 19, 2018 at 11:02
  • \$\begingroup\$ The general idea is that its better to combine textures together, especially if you try to mean constrains like power of 2 sizes. Several atlases would be a good idea to start with. I'm not sure what you mean by "it would require a lot of calculations and possible problems". Drawing an objects using an atlas as source shouldn't be any more resource intensive than objects that use a single texture as source. \$\endgroup\$ Dec 19, 2018 at 11:10
  • \$\begingroup\$ @TomTsagk by the "require a lot of calculations" I mean translating "block texture id" to UV coordinates and possible problems with floating-point numbers. \$\endgroup\$
    – Abit Gray
    Dec 19, 2018 at 11:15
  • \$\begingroup\$ I'm not familiar how minecraft works behind the scenes, by if you save all blocks as .ply or a similar format, you can save UV's there, and achieve the same result with not having to do any calculations at all, \$\endgroup\$ Dec 19, 2018 at 11:24

1 Answer 1

0
\$\begingroup\$

2D Image Limit is 8192. That means much more textures then using any type of array.

Using this for only 1 atlas means:

  • 16x ~ 262,144
  • 32x ~ 65,536
  • 64x ~ 16,384
  • 128x ~ 4,096
  • 256x ~ 1,024
  • 1024x ~ 256

16x means 16x16 pixels per texture, 32x means 32x32 and so on.

Exceeding this limit would require creating more VkImage -> VkPipeline (and when rendering chunks, split it into more meshes).

Because of this, I may settle on keeping only 1 atlas. 32x textures means average of 2 textures per block (32,767, maximum of int16_t used for block IDs), 16x ~ 8 textures per block, 64x ~ 1 texture per 2 blocks.

This will also limit servers to use lower resolution or less block, further decreasing impact on performance.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ servers wouldn't even use the texture, servers have no use for displaying client side graphics. \$\endgroup\$
    – Krupip
    Dec 20, 2018 at 18:45
  • \$\begingroup\$ @opa The way I have it designed is having server-side mods which requires server to send all the textures to used (when he does not have it already stored, checked by hash). So the server is telling the visuals and functionality. This project is just multiple prototype tests - Vulkan, server-side-only mods and LUA. \$\endgroup\$
    – Abit Gray
    Dec 21, 2018 at 10:36
  • 1
    \$\begingroup\$ Server need only send the texture data then, again, the server does not need to render anything. Lowering or increasing texture resolution would do nothing except increase or decrease bandwidth usage on startup for new players, it does not tax the server because the server shouldn't be doing anything with the textures except serving them. \$\endgroup\$
    – Krupip
    Dec 21, 2018 at 15:17
  • \$\begingroup\$ @opa server is saying which textures and at which resolution should be used. That means if server sends texture with 128x128 resolution (2^7) then it can only send 16,384 textures total because of limit on client's side (maximum atlas size, see the answer's text). Server is not rendering it but need to be aware of this limit. \$\endgroup\$
    – Abit Gray
    Dec 22, 2018 at 20:04
  • \$\begingroup\$ @AbitGray: No, it doesn't. It should send the available data; it's up to the client to decide how to render the available data. If it wants to reduce the resolution of some images, it can. If it has some hardware limitation, then the client should figure out how best to deal with it. \$\endgroup\$ Feb 15, 2019 at 19:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .