Moved VirtualTextureOutput out of VoxelMesher
This commit is contained in:
parent
92b3c25292
commit
5943b1d549
@ -554,7 +554,7 @@ NormalMapImages store_normalmap_data_to_images(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
images.atlas_images = tile_images;
|
images.atlas = tile_images;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -590,7 +590,7 @@ NormalMapImages store_normalmap_data_to_images(
|
|||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instantiate();
|
image.instantiate();
|
||||||
image->create_from_data(sqri, sqri, false, Image::FORMAT_RGB8, bytes);
|
image->create_from_data(sqri, sqri, false, Image::FORMAT_RGB8, bytes);
|
||||||
images.lookup_image = image;
|
images.lookup = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
return images;
|
return images;
|
||||||
@ -606,14 +606,14 @@ NormalMapTextures store_normalmap_data_to_textures(const NormalMapImages &data)
|
|||||||
ZN_PROFILE_SCOPE_NAMED("Atlas texture");
|
ZN_PROFILE_SCOPE_NAMED("Atlas texture");
|
||||||
Ref<Texture2DArray> atlas;
|
Ref<Texture2DArray> atlas;
|
||||||
atlas.instantiate();
|
atlas.instantiate();
|
||||||
const Error err = atlas->create_from_images(data.atlas_images);
|
const Error err = atlas->create_from_images(data.atlas);
|
||||||
ZN_ASSERT_RETURN_V(err == OK, textures);
|
ZN_ASSERT_RETURN_V(err == OK, textures);
|
||||||
textures.atlas = atlas;
|
textures.atlas = atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ZN_PROFILE_SCOPE_NAMED("Lookup image+texture");
|
ZN_PROFILE_SCOPE_NAMED("Lookup image+texture");
|
||||||
Ref<ImageTexture> lookup = ImageTexture::create_from_image(data.lookup_image);
|
Ref<ImageTexture> lookup = ImageTexture::create_from_image(data.lookup);
|
||||||
textures.lookup = lookup;
|
textures.lookup = lookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ void compute_normalmap(ICellIterator &cell_iterator, Span<const Vector3f> mesh_v
|
|||||||
Vector3i origin_in_voxels, unsigned int lod_index, bool octahedral_encoding);
|
Vector3i origin_in_voxels, unsigned int lod_index, bool octahedral_encoding);
|
||||||
|
|
||||||
struct NormalMapImages {
|
struct NormalMapImages {
|
||||||
Vector<Ref<Image>> atlas_images;
|
Vector<Ref<Image>> atlas;
|
||||||
Ref<Image> lookup_image;
|
Ref<Image> lookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NormalMapTextures {
|
struct NormalMapTextures {
|
||||||
@ -101,6 +101,15 @@ NormalMapImages store_normalmap_data_to_images(
|
|||||||
// This may not be allowed to run in a different thread than the main thread if the renderer is not using Vulkan.
|
// This may not be allowed to run in a different thread than the main thread if the renderer is not using Vulkan.
|
||||||
NormalMapTextures store_normalmap_data_to_textures(const NormalMapImages &data);
|
NormalMapTextures store_normalmap_data_to_textures(const NormalMapImages &data);
|
||||||
|
|
||||||
|
struct VirtualTextureOutput {
|
||||||
|
// Normalmap atlas used for smooth voxels.
|
||||||
|
// If textures can't be created from threads, images are returned instead.
|
||||||
|
NormalMapImages normalmap_images;
|
||||||
|
NormalMapTextures normalmap_textures;
|
||||||
|
// Can be false if textures are computed asynchronously. Will become true when it's done (and not change after).
|
||||||
|
std::atomic_bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace zylann::voxel
|
} // namespace zylann::voxel
|
||||||
|
|
||||||
#endif // VOXEL_DISTANCE_NORMALMAPS_H
|
#endif // VOXEL_DISTANCE_NORMALMAPS_H
|
||||||
|
@ -27,11 +27,9 @@ void GenerateDistanceNormalmapTask::run(ThreadedTaskContext ctx) {
|
|||||||
|
|
||||||
if (VoxelEngine::get_singleton().is_threaded_mesh_resource_building_enabled()) {
|
if (VoxelEngine::get_singleton().is_threaded_mesh_resource_building_enabled()) {
|
||||||
NormalMapTextures textures = store_normalmap_data_to_textures(images);
|
NormalMapTextures textures = store_normalmap_data_to_textures(images);
|
||||||
virtual_textures->normalmap_atlas = textures.atlas;
|
virtual_textures->normalmap_textures = textures;
|
||||||
virtual_textures->cell_lookup = textures.lookup;
|
|
||||||
} else {
|
} else {
|
||||||
virtual_textures->normalmap_atlas_images = images.atlas_images;
|
virtual_textures->normalmap_images = images;
|
||||||
virtual_textures->cell_lookup_image = images.lookup_image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual_textures->valid = true;
|
virtual_textures->valid = true;
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
NormalMapSettings virtual_texture_settings;
|
NormalMapSettings virtual_texture_settings;
|
||||||
|
|
||||||
// Output (to be assigned so it can be populated)
|
// Output (to be assigned so it can be populated)
|
||||||
std::shared_ptr<VoxelMesher::VirtualTextureOutput> virtual_textures;
|
std::shared_ptr<VirtualTextureOutput> virtual_textures;
|
||||||
|
|
||||||
// Identification
|
// Identification
|
||||||
Vector3i block_position;
|
Vector3i block_position;
|
||||||
|
@ -326,13 +326,11 @@ void MeshBlockTask::run(zylann::ThreadedTaskContext ctx) {
|
|||||||
const Vector3i block_size =
|
const Vector3i block_size =
|
||||||
voxels.get_size() - Vector3iUtil::create(mesher->get_minimum_padding() + mesher->get_maximum_padding());
|
voxels.get_size() - Vector3iUtil::create(mesher->get_minimum_padding() + mesher->get_maximum_padding());
|
||||||
|
|
||||||
ZN_ASSERT(_surfaces_output.virtual_textures == nullptr);
|
std::shared_ptr<VirtualTextureOutput> virtual_textures = make_shared_instance<VirtualTextureOutput>();
|
||||||
std::shared_ptr<VoxelMesher::VirtualTextureOutput> virtual_textures =
|
|
||||||
make_shared_instance<VoxelMesher::VirtualTextureOutput>();
|
|
||||||
virtual_textures->valid = false;
|
virtual_textures->valid = false;
|
||||||
// This is stored here in case virtual texture rendering completes before the output of the current task gets
|
// This is stored here in case virtual texture rendering completes before the output of the current task gets
|
||||||
// dequeued in the main thread, since it runs in a separate asynchronous task
|
// dequeued in the main thread, since it runs in a separate asynchronous task
|
||||||
_surfaces_output.virtual_textures = virtual_textures;
|
_virtual_textures = virtual_textures;
|
||||||
|
|
||||||
GenerateDistanceNormalmapTask *nm_task = ZN_NEW(GenerateDistanceNormalmapTask);
|
GenerateDistanceNormalmapTask *nm_task = ZN_NEW(GenerateDistanceNormalmapTask);
|
||||||
nm_task->cell_iterator = std::move(cell_iterator);
|
nm_task->cell_iterator = std::move(cell_iterator);
|
||||||
@ -397,6 +395,7 @@ void MeshBlockTask::apply_result() {
|
|||||||
o.mesh = _mesh;
|
o.mesh = _mesh;
|
||||||
o.mesh_material_indices = std::move(_mesh_material_indices);
|
o.mesh_material_indices = std::move(_mesh_material_indices);
|
||||||
o.has_mesh_resource = _has_mesh_resource;
|
o.has_mesh_resource = _has_mesh_resource;
|
||||||
|
o.virtual_textures = _virtual_textures;
|
||||||
|
|
||||||
VoxelEngine::VolumeCallbacks callbacks = VoxelEngine::get_singleton().get_volume_callbacks(volume_id);
|
VoxelEngine::VolumeCallbacks callbacks = VoxelEngine::get_singleton().get_volume_callbacks(volume_id);
|
||||||
ERR_FAIL_COND(callbacks.mesh_output_callback == nullptr);
|
ERR_FAIL_COND(callbacks.mesh_output_callback == nullptr);
|
||||||
|
@ -49,6 +49,7 @@ private:
|
|||||||
VoxelMesher::Output _surfaces_output;
|
VoxelMesher::Output _surfaces_output;
|
||||||
Ref<Mesh> _mesh;
|
Ref<Mesh> _mesh;
|
||||||
std::vector<uint8_t> _mesh_material_indices; // Indexed by mesh surface
|
std::vector<uint8_t> _mesh_material_indices; // Indexed by mesh surface
|
||||||
|
std::shared_ptr<VirtualTextureOutput> _virtual_textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ref<ArrayMesh> build_mesh(Span<const VoxelMesher::Output::Surface> surfaces, Mesh::PrimitiveType primitive, int flags,
|
Ref<ArrayMesh> build_mesh(Span<const VoxelMesher::Output::Surface> surfaces, Mesh::PrimitiveType primitive, int flags,
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "../util/tasks/progressive_task_runner.h"
|
#include "../util/tasks/progressive_task_runner.h"
|
||||||
#include "../util/tasks/threaded_task_runner.h"
|
#include "../util/tasks/threaded_task_runner.h"
|
||||||
#include "../util/tasks/time_spread_task_runner.h"
|
#include "../util/tasks/time_spread_task_runner.h"
|
||||||
|
#include "distance_normalmaps.h"
|
||||||
#include "priority_dependency.h"
|
#include "priority_dependency.h"
|
||||||
|
|
||||||
namespace zylann::voxel {
|
namespace zylann::voxel {
|
||||||
@ -38,6 +39,9 @@ public:
|
|||||||
uint8_t lod;
|
uint8_t lod;
|
||||||
// Tells if the mesh resource was built as part of the task. If not, you need to build it on the main thread.
|
// Tells if the mesh resource was built as part of the task. If not, you need to build it on the main thread.
|
||||||
bool has_mesh_resource;
|
bool has_mesh_resource;
|
||||||
|
// Can be null. Attached to meshing output so it is tracked more easily, because it is baked asynchronously
|
||||||
|
// starting from the mesh task, and it might complete earlier or later than the mesh.
|
||||||
|
std::shared_ptr<VirtualTextureOutput> virtual_textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockDataOutput {
|
struct BlockDataOutput {
|
||||||
@ -62,7 +66,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BlockVirtualTextureOutput {
|
struct BlockVirtualTextureOutput {
|
||||||
std::shared_ptr<VoxelMesher::VirtualTextureOutput> virtual_textures;
|
std::shared_ptr<VirtualTextureOutput> virtual_textures;
|
||||||
Vector3i position;
|
Vector3i position;
|
||||||
uint32_t lod_index;
|
uint32_t lod_index;
|
||||||
};
|
};
|
||||||
|
@ -46,18 +46,6 @@ public:
|
|||||||
bool virtual_texture_hint = false;
|
bool virtual_texture_hint = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Might move out of meshers because it is baked (mostly) independtly from meshers.
|
|
||||||
struct VirtualTextureOutput {
|
|
||||||
// Normalmap atlas used for smooth voxels.
|
|
||||||
// If textures can't be created from threads, images are returned instead.
|
|
||||||
Ref<Texture2DArray> normalmap_atlas;
|
|
||||||
Vector<Ref<Image>> normalmap_atlas_images;
|
|
||||||
Ref<Texture2D> cell_lookup;
|
|
||||||
Ref<Image> cell_lookup_image;
|
|
||||||
// Can be false if textures are computed asynchronously. Will become true when it's done (and not change after).
|
|
||||||
std::atomic_bool valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Output {
|
struct Output {
|
||||||
struct Surface {
|
struct Surface {
|
||||||
Array arrays;
|
Array arrays;
|
||||||
@ -83,11 +71,6 @@ public:
|
|||||||
// May be used to store extra information needed in shader to render the mesh properly
|
// May be used to store extra information needed in shader to render the mesh properly
|
||||||
// (currently used only by the cubes mesher when baking colors)
|
// (currently used only by the cubes mesher when baking colors)
|
||||||
Ref<Image> atlas_image;
|
Ref<Image> atlas_image;
|
||||||
|
|
||||||
// Can be null. Attached to meshing output so it is tracked more easily, because it is baked asynchronously and
|
|
||||||
// it might complete earlier or later than the mesh.
|
|
||||||
// TODO Might be moved to meshing task output instead, meshers don't actually use this field.
|
|
||||||
std::shared_ptr<VirtualTextureOutput> virtual_textures;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool is_mesh_empty(const std::vector<Output::Surface> &surfaces);
|
static bool is_mesh_empty(const std::vector<Output::Surface> &surfaces);
|
||||||
|
@ -1781,8 +1781,8 @@ void VoxelLodTerrain::apply_mesh_update(VoxelEngine::BlockMeshOutput &ob) {
|
|||||||
|
|
||||||
block->set_parent_transform(get_global_transform());
|
block->set_parent_transform(get_global_transform());
|
||||||
|
|
||||||
if (ob.surfaces.virtual_textures != nullptr && ob.surfaces.virtual_textures->valid) {
|
if (ob.virtual_textures != nullptr && ob.virtual_textures->valid) {
|
||||||
apply_virtual_texture_update_to_block(*block, *ob.surfaces.virtual_textures, ob.lod);
|
apply_virtual_texture_update_to_block(*block, *ob.virtual_textures, ob.lod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
@ -1813,19 +1813,15 @@ void VoxelLodTerrain::apply_virtual_texture_update(VoxelEngine::BlockVirtualText
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VoxelLodTerrain::apply_virtual_texture_update_to_block(
|
void VoxelLodTerrain::apply_virtual_texture_update_to_block(
|
||||||
VoxelMeshBlockVLT &block, VoxelMesher::VirtualTextureOutput &ob, unsigned int lod_index) {
|
VoxelMeshBlockVLT &block, VirtualTextureOutput &ob, unsigned int lod_index) {
|
||||||
ZN_PROFILE_SCOPE();
|
ZN_PROFILE_SCOPE();
|
||||||
ZN_ASSERT(ob.valid);
|
ZN_ASSERT(ob.valid);
|
||||||
|
|
||||||
NormalMapTextures normalmap_textures;
|
NormalMapTextures normalmap_textures = ob.normalmap_textures;
|
||||||
normalmap_textures.atlas = ob.normalmap_atlas;
|
|
||||||
normalmap_textures.lookup = ob.cell_lookup;
|
|
||||||
|
|
||||||
if (normalmap_textures.lookup.is_null()) {
|
if (normalmap_textures.lookup.is_null()) {
|
||||||
// TODO When this code path is required, use a time-spread task to reduce stalls
|
// TODO When this code path is required, use a time-spread task to reduce stalls
|
||||||
NormalMapImages normalmap_images;
|
NormalMapImages normalmap_images = ob.normalmap_images;
|
||||||
normalmap_images.atlas_images = ob.normalmap_atlas_images;
|
|
||||||
normalmap_images.lookup_image = ob.cell_lookup_image;
|
|
||||||
normalmap_textures = store_normalmap_data_to_textures(normalmap_images);
|
normalmap_textures = store_normalmap_data_to_textures(normalmap_images);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ private:
|
|||||||
void apply_data_block_response(VoxelEngine::BlockDataOutput &ob);
|
void apply_data_block_response(VoxelEngine::BlockDataOutput &ob);
|
||||||
void apply_virtual_texture_update(VoxelEngine::BlockVirtualTextureOutput &ob);
|
void apply_virtual_texture_update(VoxelEngine::BlockVirtualTextureOutput &ob);
|
||||||
void apply_virtual_texture_update_to_block(
|
void apply_virtual_texture_update_to_block(
|
||||||
VoxelMeshBlockVLT &block, VoxelMesher::VirtualTextureOutput &ob, unsigned int lod_index);
|
VoxelMeshBlockVLT &block, VirtualTextureOutput &ob, unsigned int lod_index);
|
||||||
|
|
||||||
void start_updater();
|
void start_updater();
|
||||||
void stop_updater();
|
void stop_updater();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user