Skip to content

Commit

Permalink
Use more bits to store material indices beyond 255
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Dec 17, 2023
1 parent e5f086f commit dd26524
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 17 deletions.
2 changes: 1 addition & 1 deletion engine/voxel_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class VoxelEngine {
// Remaps Mesh surface indices to Mesher material indices. Only used if `has_mesh_resource` is true.
// TODO Optimize: candidate for small vector optimization. A big majority of meshes will have a handful of
// surfaces, which would fit here without allocating.
std::vector<uint8_t> mesh_material_indices;
std::vector<uint16_t> mesh_material_indices;
// In mesh block coordinates
Vector3i position;
// TODO Rename lod_index
Expand Down
1 change: 1 addition & 0 deletions meshers/blocky/voxel_blocky_library_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void VoxelBlockyLibraryBase::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_tangents"), "set_bake_tangents", "get_bake_tangents");

BIND_CONSTANT(MAX_MODELS);
BIND_CONSTANT(MAX_MATERIALS);
}

template <typename F>
Expand Down
6 changes: 6 additions & 0 deletions meshers/blocky/voxel_blocky_library_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class VoxelBlockyLibraryBase : public Resource {
public:
// Limit based on maximum supported by VoxelMesherBlocky
static const unsigned int MAX_MODELS = 65536;

// Materials must be kept to a minimum. 256 is already a lot, but that only affects performance. This limit is
// the one beyond which the code stops working. Could still be increased in theory (requires some code changes to
// use uint32_t instead of uint16_t), but there is no practical sense doing so.
static const unsigned int MAX_MATERIALS = 65536;

static const uint32_t NULL_INDEX = 0xFFFFFFFF;

struct BakedData {
Expand Down
19 changes: 19 additions & 0 deletions meshers/blocky/voxel_blocky_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@

namespace zylann::voxel {

unsigned int VoxelBlockyModel::MaterialIndexer::get_or_create_index(const Ref<Material> &p_material) {
for (size_t i = 0; i < materials.size(); ++i) {
const Ref<Material> &material = materials[i];
if (material == p_material) {
return i;
}
}
#ifdef TOOLS_ENABLED
if (materials.size() == VoxelBlockyLibraryBase::MAX_MATERIALS) {
ZN_PRINT_ERROR(format("Maximum material count reached ({}), try reduce your number of materials by re-using "
"them or using atlases.",
VoxelBlockyLibraryBase::MAX_MATERIALS));
}
#endif
const unsigned int ret = materials.size();
materials.push_back(p_material);
return ret;
}

VoxelBlockyModel::VoxelBlockyModel() : _color(1.f, 1.f, 1.f) {}

bool VoxelBlockyModel::_set(const StringName &p_name, const Variant &p_value) {
Expand Down
12 changes: 1 addition & 11 deletions meshers/blocky/voxel_blocky_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,17 +165,7 @@ class VoxelBlockyModel : public Resource {
struct MaterialIndexer {
std::vector<Ref<Material>> &materials;

unsigned int get_or_create_index(const Ref<Material> &p_material) {
for (size_t i = 0; i < materials.size(); ++i) {
const Ref<Material> &material = materials[i];
if (material == p_material) {
return i;
}
}
const unsigned int ret = materials.size();
materials.push_back(p_material);
return ret;
}
unsigned int get_or_create_index(const Ref<Material> &p_material);
};

virtual void bake(BakedData &baked_data, bool bake_tangents, MaterialIndexer &materials) const;
Expand Down
2 changes: 1 addition & 1 deletion meshers/mesh_block_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static void copy_block_and_neighbors(Span<std::shared_ptr<VoxelBufferInternal>>
Ref<ArrayMesh> build_mesh(Span<const VoxelMesher::Output::Surface> surfaces, Mesh::PrimitiveType primitive, int flags,
// This vector indexes surfaces to the material they use (if a surface uses a material but is empty, it
// won't be added to the mesh)
std::vector<uint8_t> &mesh_material_indices) {
std::vector<uint16_t> &mesh_material_indices) {
ZN_PROFILE_SCOPE();
ZN_ASSERT(mesh_material_indices.size() == 0);

Expand Down
4 changes: 2 additions & 2 deletions meshers/mesh_block_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class MeshBlockTask : public IGeneratingVoxelsThreadedTask {
VoxelBufferInternal _voxels;
VoxelMesher::Output _surfaces_output;
Ref<Mesh> _mesh;
std::vector<uint8_t> _mesh_material_indices; // Indexed by mesh surface
std::vector<uint16_t> _mesh_material_indices; // Indexed by mesh surface
std::shared_ptr<DetailTextureOutput> _detail_textures;
std::vector<GenerateBlockGPUTaskResult> _gpu_generation_results;
};

Ref<ArrayMesh> build_mesh(Span<const VoxelMesher::Output::Surface> surfaces, Mesh::PrimitiveType primitive, int flags,
std::vector<uint8_t> &surface_indices);
std::vector<uint16_t> &mesh_material_indices);

} // namespace zylann::voxel

Expand Down
2 changes: 1 addition & 1 deletion meshers/voxel_mesher.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class VoxelMesher : public Resource {
struct Output {
struct Surface {
Array arrays;
uint8_t material_index = 0;
uint16_t material_index = 0;
};
std::vector<Surface> surfaces;
FixedArray<std::vector<Surface>, Cube::SIDE_COUNT> transition_surfaces;
Expand Down
2 changes: 1 addition & 1 deletion terrain/fixed_lod/voxel_terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1705,7 +1705,7 @@ void VoxelTerrain::apply_mesh_update(const VoxelEngine::BlockMeshOutput &ob) {
}

Ref<ArrayMesh> mesh;
std::vector<uint8_t> material_indices;
std::vector<uint16_t> material_indices;
if (ob.has_mesh_resource) {
// The mesh was already built as part of the threaded task
mesh = ob.mesh;
Expand Down

0 comments on commit dd26524

Please sign in to comment.