Skip to content

Commit

Permalink
Fix possible artifacts at terrain boundaries.
Browse files Browse the repository at this point in the history
Was caused by a buffer getting re-used without re-initializing its data,
combined with a generator that was assuming the buffer was initialized to
defaults (and filling nothing due to going through an early-out
optimization)
  • Loading branch information
Zylann committed Mar 5, 2024
1 parent 534bcb5 commit 4866275
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 14 deletions.
1 change: 1 addition & 0 deletions doc/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Primarily developped with Godot 4.2.
- Fixed `"plugins_list.has(p_plugin)" is true` errors in the editor, at the cost of slight behavior changes. This was caused by existing workarounds to prevent UIs from hiding unexpectedly, which were modified to avoid the error, but are still needed unfortunately.
- Fixed error `Unimplemented _get_import_order in add-on` when importing `.vox` files
- Fixed some corner cases where quickly leaving and coming back to an edited area would revert edits to their previous state, due to chunks reloading before those edits got saved asynchronously
- Fixed possible artifacts near terrain borders when using generators that sometimes avoid filling the output buffer, assuming they are initialized to defaults (issue #603)
- `VoxelGeneratorGraph`:
- Fixed ambiguous voxel texture indices produced by `OutputSingleTexture` caused painting to fail in some situations
- Fixed default input values of output nodes were always 0 when using GPU generation
Expand Down
1 change: 1 addition & 0 deletions meshers/mesh_block_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ static void copy_block_and_neighbors(Span<std::shared_ptr<VoxelBufferInternal>>
mesh_block_pos * (area_info.mesh_block_size_factor * data_block_size << lod_index) -
Vector3iUtil::create(min_padding << lod_index);

// Undo padding to go back to proper buffer coordinates
for (Box3i &box : boxes_to_generate) {
box.pos += Vector3iUtil::create(min_padding);
}
Expand Down
22 changes: 8 additions & 14 deletions storage/voxel_buffer_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,29 +171,23 @@ void VoxelBufferInternal::create(unsigned int sx, unsigned int sy, unsigned int
ZN_DSTACK();
ZN_ASSERT_RETURN(sx <= MAX_SIZE && sy <= MAX_SIZE && sz <= MAX_SIZE);

clear_voxel_metadata();
// Always clear everything even if size doesn't change, because at least we want to start from default.
// If one day we really want some hypothetic performance trying to re-use previously allocated data,
// we could add a `create_no_reset` method.
clear();

#ifdef TOOLS_ENABLED
if (sx == 0 || sy == 0 || sz == 0) {
ZN_PRINT_WARNING(format(
"VoxelBuffer::create called with empty size ({}, {}, {}). It will be cleared instead.", sx, sy, sz));
clear();
return;
}
#endif

const Vector3i new_size(sx, sy, sz);
if (new_size != _size) {
// Assign size first, because `create_channel` uses it
_size = new_size;
for (unsigned int i = 0; i < _channels.size(); ++i) {
Channel &channel = _channels[i];
if (channel.data != nullptr) {
// Channel already contained data
delete_channel(i);
ZN_ASSERT_RETURN(create_channel(i, channel.defval));
}
}
// Assign size first, because `create_channel` uses it
_size = Vector3i(sx, sy, sz);
for (unsigned int i = 0; i < _channels.size(); ++i) {
ZN_ASSERT_RETURN(create_channel(i, g_default_values[i]));
}
}

Expand Down

0 comments on commit 4866275

Please sign in to comment.