diff --git a/engine/generate_distance_normalmap_task.cpp b/engine/generate_distance_normalmap_task.cpp index 76cf6711..0e630324 100644 --- a/engine/generate_distance_normalmap_task.cpp +++ b/engine/generate_distance_normalmap_task.cpp @@ -6,6 +6,31 @@ namespace zylann::voxel { +/*static void debug_dump_atlas(Vector> images, String fpath) { + if (images.size() == 0) { + return; + } + const int tile_width = images[0]->get_width(); + const int tile_height = images[0]->get_height(); + const int sqri = int(Math::ceil(Math::sqrt(float(images.size())))); + const int atlas_width = sqri * tile_width; + const int atlas_height = sqri * tile_height; + Ref atlas; + atlas.instantiate(); + atlas->create(atlas_width, atlas_height, false, images[0]->get_format()); + for (int layer_index = 0; layer_index < images.size(); ++layer_index) { + Ref im = images[layer_index]; + const int xi = layer_index % sqri; + const int yi = layer_index / sqri; + atlas->blit_rect( + im, Rect2(0, 0, im->get_width(), im->get_height()), Vector2(xi * tile_width, yi * tile_height)); + } + const int err = atlas->save_png(fpath); + if (err != OK) { + print_line(String("Could not save {0}, err {1}").format(varray(fpath, err))); + } +}*/ + void GenerateDistanceNormalmapTask::run(ThreadedTaskContext ctx) { ZN_PROFILE_SCOPE(); ZN_ASSERT_RETURN(generator.is_valid()); @@ -19,12 +44,25 @@ void GenerateDistanceNormalmapTask::run(ThreadedTaskContext ctx) { const unsigned int tile_resolution = get_virtual_texture_tile_resolution_for_lod(virtual_texture_settings, lod_index); + const Vector3i origin_in_voxels = mesh_block_position * (mesh_block_size << lod_index); + compute_normalmap(*cell_iterator, to_span(mesh_vertices), to_span(mesh_normals), to_span(mesh_indices), tls_normalmap_data, tile_resolution, **generator, voxel_data.get(), origin_in_voxels, lod_index, virtual_texture_settings.octahedral_encoding_enabled); NormalMapImages images = store_normalmap_data_to_images( - tls_normalmap_data, tile_resolution, block_size, virtual_texture_settings.octahedral_encoding_enabled); + tls_normalmap_data, tile_resolution, mesh_block_size, virtual_texture_settings.octahedral_encoding_enabled); + + // Debug + // debug_dump_atlas(images.atlas, + // String("debug_data/debug_normalmap_atlas_{0}_{1}_{2}_lod{3}_n{4}.png") + // .format(varray(mesh_block_position.x, mesh_block_position.y, mesh_block_position.z, lod_index, + // images.atlas.size()))); + // if (images.lookup.is_valid()) { + // images.lookup->save_png(String("debug_data/debug_lookup_{0}_{1}_{2}_lod{3}.png") + // .format(varray(mesh_block_position.x, mesh_block_position.y, + // mesh_block_position.z, lod_index))); + // } if (VoxelEngine::get_singleton().is_threaded_mesh_resource_building_enabled()) { NormalMapTextures textures = store_normalmap_data_to_textures(images); @@ -46,7 +84,7 @@ void GenerateDistanceNormalmapTask::apply_result() { VoxelEngine::BlockVirtualTextureOutput o; // TODO Check for invalidation due to property changes - o.position = block_position; + o.position = mesh_block_position; o.lod_index = lod_index; o.virtual_textures = virtual_textures; diff --git a/engine/generate_distance_normalmap_task.h b/engine/generate_distance_normalmap_task.h index e71ce624..16593830 100644 --- a/engine/generate_distance_normalmap_task.h +++ b/engine/generate_distance_normalmap_task.h @@ -25,8 +25,7 @@ public: std::vector mesh_indices; Ref generator; std::shared_ptr voxel_data; - Vector3i origin_in_voxels; - Vector3i block_size; + Vector3i mesh_block_size; uint8_t lod_index; NormalMapSettings virtual_texture_settings; @@ -34,7 +33,7 @@ public: std::shared_ptr virtual_textures; // Identification - Vector3i block_position; + Vector3i mesh_block_position; uint32_t volume_id; PriorityDependency priority_dependency; diff --git a/engine/mesh_block_task.cpp b/engine/mesh_block_task.cpp index 00d27085..471ba006 100644 --- a/engine/mesh_block_task.cpp +++ b/engine/mesh_block_task.cpp @@ -264,7 +264,7 @@ void MeshBlockTask::run(zylann::ThreadedTaskContext ctx) { VoxelBufferInternal voxels; copy_block_and_neighbors(to_span(blocks, blocks_count), voxels, min_padding, max_padding, mesher->get_used_channels_mask(), meshing_dependency->generator, modifiers, data_block_size, lod_index, - position); + mesh_block_position); // Could cache generator data from here if it was safe to write into the map /*if (data != nullptr && cache_generated_blocks) { @@ -299,7 +299,10 @@ void MeshBlockTask::run(zylann::ThreadedTaskContext ctx) { } }*/ - const Vector3i origin_in_voxels = position * (int(data_block_size) << lod_index); + const Vector3i mesh_block_size = + voxels.get_size() - Vector3iUtil::create(mesher->get_minimum_padding() + mesher->get_maximum_padding()); + + const Vector3i origin_in_voxels = mesh_block_position * (mesh_block_size << lod_index); const VoxelMesher::Input input = { voxels, meshing_dependency->generator.ptr(), data.get(), origin_in_voxels, lod_index, collision_hint, lod_hint, true }; @@ -323,9 +326,6 @@ void MeshBlockTask::run(zylann::ThreadedTaskContext ctx) { UniquePtr cell_iterator = make_unique_instance(cell_infos); - const Vector3i block_size = - voxels.get_size() - Vector3iUtil::create(mesher->get_minimum_padding() + mesher->get_maximum_padding()); - std::shared_ptr virtual_textures = make_shared_instance(); virtual_textures->valid = false; // This is stored here in case virtual texture rendering completes before the output of the current task gets @@ -339,10 +339,9 @@ void MeshBlockTask::run(zylann::ThreadedTaskContext ctx) { nm_task->mesh_indices = mesh_arrays.indices; nm_task->generator = meshing_dependency->generator; nm_task->voxel_data = data; - nm_task->origin_in_voxels = origin_in_voxels; - nm_task->block_size = block_size; + nm_task->mesh_block_size = mesh_block_size; nm_task->lod_index = lod_index; - nm_task->block_position = position; + nm_task->mesh_block_position = mesh_block_position; nm_task->volume_id = volume_id; nm_task->virtual_textures = virtual_textures; nm_task->virtual_texture_settings = virtual_texture_settings; @@ -391,7 +390,7 @@ void MeshBlockTask::apply_result() { o.type = VoxelEngine::BlockMeshOutput::TYPE_DROPPED; } - o.position = position; + o.position = mesh_block_position; o.lod = lod_index; o.surfaces = std::move(_surfaces_output); o.mesh = _mesh; diff --git a/engine/mesh_block_task.h b/engine/mesh_block_task.h index c68478c5..a5d44ed5 100644 --- a/engine/mesh_block_task.h +++ b/engine/mesh_block_task.h @@ -27,7 +27,7 @@ public: FixedArray, constants::MAX_BLOCK_COUNT_PER_REQUEST> blocks; // TODO Need to provide format //FixedArray channel_depths; - Vector3i position; // In mesh blocks of the specified lod + Vector3i mesh_block_position; // In mesh blocks of the specified lod uint32_t volume_id; uint8_t lod_index = 0; uint8_t blocks_count = 0; diff --git a/meshers/transvoxel/voxel_mesher_transvoxel.cpp b/meshers/transvoxel/voxel_mesher_transvoxel.cpp index 8f365f6e..3e1a488e 100644 --- a/meshers/transvoxel/voxel_mesher_transvoxel.cpp +++ b/meshers/transvoxel/voxel_mesher_transvoxel.cpp @@ -201,31 +201,6 @@ struct DeepSampler : transvoxel::IDeepSDFSampler { } }; -/*static void debug_dump_atlas(Vector> images, String fpath) { - if (images.size() == 0) { - return; - } - const int tile_width = images[0]->get_width(); - const int tile_height = images[0]->get_height(); - const int sqri = int(Math::ceil(Math::sqrt(float(images.size())))); - const int atlas_width = sqri * tile_width; - const int atlas_height = sqri * tile_height; - Ref atlas; - atlas.instantiate(); - atlas->create(atlas_width, atlas_height, false, images[0]->get_format()); - for (int layer_index = 0; layer_index < images.size(); ++layer_index) { - Ref im = images[layer_index]; - const int xi = layer_index % sqri; - const int yi = layer_index / sqri; - atlas->blit_rect( - im, Rect2(0, 0, im->get_width(), im->get_height()), Vector2(xi * tile_width, yi * tile_height)); - } - const int err = atlas->save_png(fpath); - if (err != OK) { - print_line(String("Could not save {0}, err {1}").format(varray(fpath, err))); - } -}*/ - void VoxelMesherTransvoxel::build(VoxelMesher::Output &output, const VoxelMesher::Input &input) { ZN_PROFILE_SCOPE(); diff --git a/register_types.cpp b/register_types.cpp index 5a57be41..3c1c50c4 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -235,6 +235,10 @@ void initialize_voxel_module(ModuleInitializationLevel p_level) { ZN_PRINT_VERBOSE(format("Size of VoxelDataMap: {}", sizeof(VoxelDataMap))); ZN_PRINT_VERBOSE(format("Size of VoxelMesher::Output: {}", sizeof(VoxelMesher::Output))); ZN_PRINT_VERBOSE(format("Size of VoxelEngine::BlockMeshOutput: {}", sizeof(VoxelEngine::BlockMeshOutput))); + if (RenderingDevice::get_singleton() != nullptr) { + ZN_PRINT_VERBOSE(format("TextureArray max layers: {}", + RenderingDevice::get_singleton()->limit_get(RenderingDevice::LIMIT_MAX_TEXTURE_ARRAY_LAYERS))); + } #ifdef VOXEL_RUN_TESTS zylann::voxel::tests::run_voxel_tests(); diff --git a/terrain/fixed_lod/voxel_terrain.cpp b/terrain/fixed_lod/voxel_terrain.cpp index 1f12fe1d..311c9e00 100644 --- a/terrain/fixed_lod/voxel_terrain.cpp +++ b/terrain/fixed_lod/voxel_terrain.cpp @@ -1490,7 +1490,7 @@ void VoxelTerrain::process_meshing() { // We'll allocate this quite often. If it becomes a problem, it should be easy to pool. MeshBlockTask *task = ZN_NEW(MeshBlockTask); task->volume_id = _volume_id; - task->position = mesh_block_pos; + task->mesh_block_position = mesh_block_pos; task->lod_index = 0; task->meshing_dependency = _meshing_dependency; task->data_block_size = get_data_block_size(); @@ -1523,8 +1523,8 @@ void VoxelTerrain::process_meshing() { } #endif - init_sparse_grid_priority_dependency(task->priority_dependency, task->position, get_mesh_block_size(), - shared_viewers_data, volume_transform); + init_sparse_grid_priority_dependency(task->priority_dependency, task->mesh_block_position, + get_mesh_block_size(), shared_viewers_data, volume_transform); VoxelEngine::get_singleton().push_async_task(task); diff --git a/terrain/variable_lod/voxel_lod_terrain_update_task.cpp b/terrain/variable_lod/voxel_lod_terrain_update_task.cpp index c31649f3..6854a5c0 100644 --- a/terrain/variable_lod/voxel_lod_terrain_update_task.cpp +++ b/terrain/variable_lod/voxel_lod_terrain_update_task.cpp @@ -1220,7 +1220,7 @@ static void send_mesh_requests(uint32_t volume_id, VoxelLodTerrainUpdateData::St // We'll allocate this quite often. If it becomes a problem, it should be easy to pool. MeshBlockTask *task = memnew(MeshBlockTask); task->volume_id = volume_id; - task->position = mesh_block_pos; + task->mesh_block_position = mesh_block_pos; task->lod_index = lod_index; task->lod_hint = true; task->meshing_dependency = meshing_dependency; @@ -1258,8 +1258,11 @@ static void send_mesh_requests(uint32_t volume_id, VoxelLodTerrainUpdateData::St ++task->blocks_count; }); - init_sparse_octree_priority_dependency(task->priority_dependency, task->position, task->lod_index, - mesh_block_size, shared_viewers_data, volume_transform, settings.lod_distance); + // TODO There is inconsistency with coordinates sent to this function. + // Sometimes we send data block coordinates, sometimes we send mesh block coordinates. They aren't always + // the same, it might cause issues in priority sorting? + init_sparse_octree_priority_dependency(task->priority_dependency, task->mesh_block_position, + task->lod_index, mesh_block_size, shared_viewers_data, volume_transform, settings.lod_distance); task_scheduler.push_main_task(task);