Fix wrong block coordinate systems when computing normalmaps and a few other things

master
Marc Gilleron 2022-08-17 22:23:13 +01:00
parent f6d35ad97e
commit a28a172763
8 changed files with 64 additions and 46 deletions

View File

@ -6,6 +6,31 @@
namespace zylann::voxel {
/*static void debug_dump_atlas(Vector<Ref<Image>> 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<Image> 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<Image> 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;

View File

@ -25,8 +25,7 @@ public:
std::vector<int> mesh_indices;
Ref<VoxelGenerator> generator;
std::shared_ptr<VoxelDataLodMap> 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<VirtualTextureOutput> virtual_textures;
// Identification
Vector3i block_position;
Vector3i mesh_block_position;
uint32_t volume_id;
PriorityDependency priority_dependency;

View File

@ -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<TransvoxelCellIterator> cell_iterator = make_unique_instance<TransvoxelCellIterator>(cell_infos);
const Vector3i block_size =
voxels.get_size() - Vector3iUtil::create(mesher->get_minimum_padding() + mesher->get_maximum_padding());
std::shared_ptr<VirtualTextureOutput> virtual_textures = make_shared_instance<VirtualTextureOutput>();
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;

View File

@ -27,7 +27,7 @@ public:
FixedArray<std::shared_ptr<VoxelBufferInternal>, constants::MAX_BLOCK_COUNT_PER_REQUEST> blocks;
// TODO Need to provide format
//FixedArray<uint8_t, VoxelBufferInternal::MAX_CHANNELS> 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;

View File

@ -201,31 +201,6 @@ struct DeepSampler : transvoxel::IDeepSDFSampler {
}
};
/*static void debug_dump_atlas(Vector<Ref<Image>> 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<Image> 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<Image> 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();

View File

@ -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();

View File

@ -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);

View File

@ -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);