Fix wrong block coordinate systems when computing normalmaps and a few other things
This commit is contained in:
parent
f6d35ad97e
commit
a28a172763
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user