ADD: planet quadtree texture enabled

This commit is contained in:
2025-12-30 14:14:01 +09:00
parent 2bf97defcd
commit f1fa3ef780
4 changed files with 187 additions and 139 deletions

View File

@@ -2273,6 +2273,12 @@ namespace
auto settings = planets->earth_quadtree_settings(); auto settings = planets->earth_quadtree_settings();
bool changed = false; bool changed = false;
bool tint = planets->earth_debug_tint_patches_by_lod();
if (ImGui::Checkbox("Debug: tint patches by LOD", &tint))
{
planets->set_earth_debug_tint_patches_by_lod(tint);
}
int maxLevel = static_cast<int>(settings.max_level); int maxLevel = static_cast<int>(settings.max_level);
if (ImGui::SliderInt("Max LOD level", &maxLevel, 0, 20)) if (ImGui::SliderInt("Max LOD level", &maxLevel, 0, 20))
{ {

View File

@@ -192,6 +192,9 @@ namespace planet
const uint32_t skirt_vertex_count = 4u * resolution; const uint32_t skirt_vertex_count = 4u * resolution;
out_vertices.resize(static_cast<size_t>(base_vertex_count) + static_cast<size_t>(skirt_vertex_count)); out_vertices.resize(static_cast<size_t>(base_vertex_count) + static_cast<size_t>(skirt_vertex_count));
const uint32_t tiles_per_axis = (level < 31u) ? (1u << level) : 1u;
const double inv_tiles = (tiles_per_axis > 0u) ? (1.0 / static_cast<double>(tiles_per_axis)) : 1.0;
const double inv = 1.0 / static_cast<double>(resolution - 1u); const double inv = 1.0 / static_cast<double>(resolution - 1u);
const double du = (u1 - u0) * inv; const double du = (u1 - u0) * inv;
const double dv = (v1 - v0) * inv; const double dv = (v1 - v0) * inv;
@@ -215,8 +218,13 @@ namespace planet
vert.normal = glm::vec3(static_cast<float>(unit_dir.x), vert.normal = glm::vec3(static_cast<float>(unit_dir.x),
static_cast<float>(unit_dir.y), static_cast<float>(unit_dir.y),
static_cast<float>(unit_dir.z)); static_cast<float>(unit_dir.z));
vert.uv_x = s;
vert.uv_y = t; // UVs cover the entire cube face (0..1) so all patches on this face
// sample from a single per-face texture.
const double u_face = (static_cast<double>(x) + static_cast<double>(s)) * inv_tiles;
const double v_face = (static_cast<double>(y) + static_cast<double>(t)) * inv_tiles;
vert.uv_x = static_cast<float>(u_face);
vert.uv_y = static_cast<float>(v_face);
vert.color = vertex_color; vert.color = vertex_color;
vert.tangent = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); vert.tangent = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);

View File

@@ -17,7 +17,6 @@
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
#include <filesystem>
#include "device.h" #include "device.h"
@@ -79,6 +78,16 @@ void PlanetSystem::init(EngineContext *context)
_context = context; _context = context;
} }
void PlanetSystem::set_earth_debug_tint_patches_by_lod(bool enabled)
{
if (_earth_debug_tint_patches_by_lod == enabled)
{
return;
}
_earth_debug_tint_patches_by_lod = enabled;
_earth_patch_cache_dirty = true;
}
void PlanetSystem::cleanup() void PlanetSystem::cleanup()
{ {
if (!_context) if (!_context)
@@ -89,11 +98,11 @@ void PlanetSystem::cleanup()
TextureCache *textures = _context->textures; TextureCache *textures = _context->textures;
if (textures) if (textures)
{ {
for (EarthPatch &p : _earth_patches) for (MaterialInstance &mat : _earth_face_materials)
{ {
if (p.material_instance.materialSet != VK_NULL_HANDLE) if (mat.materialSet != VK_NULL_HANDLE)
{ {
textures->unwatchSet(p.material_instance.materialSet); textures->unwatchSet(mat.materialSet);
} }
} }
} }
@@ -146,6 +155,7 @@ void PlanetSystem::cleanup()
_earth_patch_lru.clear(); _earth_patch_lru.clear();
_earth_patch_free.clear(); _earth_patch_free.clear();
_earth_patches.clear(); _earth_patches.clear();
_earth_face_materials = {};
_earth_patch_index_count = 0; _earth_patch_index_count = 0;
_earth_patch_index_resolution = 0; _earth_patch_index_resolution = 0;
@@ -235,6 +245,46 @@ PlanetSystem::EarthPatch *PlanetSystem::find_earth_patch(const planet::PatchKey
return &_earth_patches[idx]; return &_earth_patches[idx];
} }
void PlanetSystem::clear_earth_patch_cache()
{
if (!_context)
{
return;
}
ResourceManager *rm = _context->getResources();
FrameResources *frame = _context->currentFrame;
if (rm)
{
for (EarthPatch &p : _earth_patches)
{
if (p.vertex_buffer.buffer == VK_NULL_HANDLE)
{
continue;
}
const AllocatedBuffer vb = p.vertex_buffer;
if (frame)
{
frame->_deletionQueue.push_function([rm, vb]() { rm->destroy_buffer(vb); });
}
else
{
rm->destroy_buffer(vb);
}
p.vertex_buffer = {};
p.vertex_buffer_address = 0;
}
}
_earth_patch_lookup.clear();
_earth_patch_lru.clear();
_earth_patch_free.clear();
_earth_patches.clear();
}
void PlanetSystem::ensure_earth_patch_index_buffer() void PlanetSystem::ensure_earth_patch_index_buffer()
{ {
if (_earth_patch_index_buffer.buffer != VK_NULL_HANDLE && _earth_patch_index_resolution == _earth_patch_resolution) if (_earth_patch_index_buffer.buffer != VK_NULL_HANDLE && _earth_patch_index_resolution == _earth_patch_resolution)
@@ -257,7 +307,6 @@ void PlanetSystem::ensure_earth_patch_index_buffer()
if (_earth_patch_index_buffer.buffer != VK_NULL_HANDLE) if (_earth_patch_index_buffer.buffer != VK_NULL_HANDLE)
{ {
FrameResources *frame = _context->currentFrame; FrameResources *frame = _context->currentFrame;
TextureCache *textures = _context->textures;
// Destroy per-patch vertex buffers. // Destroy per-patch vertex buffers.
for (const auto &kv : _earth_patch_lookup) for (const auto &kv : _earth_patch_lookup)
@@ -286,28 +335,8 @@ void PlanetSystem::ensure_earth_patch_index_buffer()
_earth_patch_lookup.clear(); _earth_patch_lookup.clear();
_earth_patch_lru.clear(); _earth_patch_lru.clear();
if (textures)
{
for (EarthPatch &p : _earth_patches)
{
if (p.material_instance.materialSet != VK_NULL_HANDLE)
{
textures->unwatchSet(p.material_instance.materialSet);
}
}
}
_earth_patch_free.clear(); _earth_patch_free.clear();
_earth_patch_free.reserve(_earth_patches.size()); _earth_patches.clear();
for (uint32_t idx = 0; idx < static_cast<uint32_t>(_earth_patches.size()); ++idx)
{
EarthPatch &p = _earth_patches[idx];
const VkDescriptorSet keep_set = p.material_instance.materialSet;
p = EarthPatch{};
p.material_instance.materialSet = keep_set;
_earth_patch_free.push_back(idx);
}
const AllocatedBuffer ib = _earth_patch_index_buffer; const AllocatedBuffer ib = _earth_patch_index_buffer;
if (frame) if (frame)
@@ -408,7 +437,7 @@ void PlanetSystem::ensure_earth_patch_material_constants_buffer()
} }
} }
void PlanetSystem::ensure_earth_patch_material_instance(EarthPatch &patch, const PlanetBody &earth) void PlanetSystem::ensure_earth_face_materials(const PlanetBody &earth)
{ {
if (!_context || !earth.material) if (!_context || !earth.material)
{ {
@@ -418,6 +447,7 @@ void PlanetSystem::ensure_earth_patch_material_instance(EarthPatch &patch, const
DeviceManager *device = _context->getDevice(); DeviceManager *device = _context->getDevice();
SamplerManager *samplers = _context->getSamplers(); SamplerManager *samplers = _context->getSamplers();
AssetManager *assets = _context->assets; AssetManager *assets = _context->assets;
TextureCache *textures = _context->textures;
if (!device || !assets) if (!device || !assets)
{ {
return; return;
@@ -438,24 +468,19 @@ void PlanetSystem::ensure_earth_patch_material_instance(EarthPatch &patch, const
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 6}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 6},
}; };
_earth_patch_material_allocator.init(device->device(), 128, sizes); _earth_patch_material_allocator.init(device->device(), 16, sizes);
_earth_patch_material_allocator_initialized = true; _earth_patch_material_allocator_initialized = true;
} }
if (patch.material_instance.materialSet == VK_NULL_HANDLE)
{
patch.material_instance.materialSet =
_earth_patch_material_allocator.allocate(device->device(), _earth_patch_material_layout);
}
patch.material_instance.pipeline = earth.material->data.pipeline;
patch.material_instance.passType = earth.material->data.passType;
VkSampler tileSampler = samplers ? samplers->linearClampEdge() : VK_NULL_HANDLE; VkSampler tileSampler = samplers ? samplers->linearClampEdge() : VK_NULL_HANDLE;
if (tileSampler == VK_NULL_HANDLE && samplers) if (tileSampler == VK_NULL_HANDLE && samplers)
{ {
tileSampler = samplers->defaultLinear(); tileSampler = samplers->defaultLinear();
} }
if (tileSampler == VK_NULL_HANDLE)
{
return;
}
VkImageView checker = assets->fallback_checkerboard_view(); VkImageView checker = assets->fallback_checkerboard_view();
VkImageView white = assets->fallback_white_view(); VkImageView white = assets->fallback_white_view();
@@ -467,92 +492,79 @@ void PlanetSystem::ensure_earth_patch_material_instance(EarthPatch &patch, const
if (flatNormal == VK_NULL_HANDLE) flatNormal = white; if (flatNormal == VK_NULL_HANDLE) flatNormal = white;
if (black == VK_NULL_HANDLE) black = white; if (black == VK_NULL_HANDLE) black = white;
if (patch.material_instance.materialSet != VK_NULL_HANDLE) auto face_legacy = [](planet::CubeFace f) -> const char * {
{ switch (f)
DescriptorWriter writer;
writer.write_buffer(0,
_earth_patch_material_constants_buffer.buffer,
sizeof(GLTFMetallic_Roughness::MaterialConstants),
0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
writer.write_image(1,
checker,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(2,
white,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(3,
flatNormal,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(4,
white,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(5,
black,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.update_set(device->device(), patch.material_instance.materialSet);
}
// Per-patch tiled textures via TextureCache (albedo only for now).
if (_context->textures && tileSampler != VK_NULL_HANDLE && patch.material_instance.materialSet != VK_NULL_HANDLE)
{
auto face_legacy = [](planet::CubeFace f) -> const char * {
switch (f)
{
case planet::CubeFace::PosX: return "px";
case planet::CubeFace::NegX: return "nx";
case planet::CubeFace::PosY: return "py";
case planet::CubeFace::NegY: return "ny";
case planet::CubeFace::PosZ: return "pz";
case planet::CubeFace::NegZ: return "nz";
}
return "px";
};
const planet::PatchKey &k = patch.key;
const uint32_t face_index = static_cast<uint32_t>(k.face);
std::vector<std::string> candidates;
candidates.reserve(2);
candidates.push_back(fmt::format("planets/earth/albedo/face{}/L{}/X{}_Y{}.ktx2", face_index, k.level, k.x, k.y));
if (k.level == 0u && k.x == 0u && k.y == 0u)
{ {
candidates.push_back(fmt::format("planets/earth/albedo/L0/{}.ktx2", face_legacy(k.face))); case planet::CubeFace::PosX: return "px";
case planet::CubeFace::NegX: return "nx";
case planet::CubeFace::PosY: return "py";
case planet::CubeFace::NegY: return "ny";
case planet::CubeFace::PosZ: return "pz";
case planet::CubeFace::NegZ: return "nz";
} }
return "px";
};
std::string resolved_path; for (size_t face_index = 0; face_index < _earth_face_materials.size(); ++face_index)
for (const std::string &rel : candidates) {
MaterialInstance &mat = _earth_face_materials[face_index];
mat.pipeline = earth.material->data.pipeline;
mat.passType = earth.material->data.passType;
if (mat.materialSet == VK_NULL_HANDLE)
{ {
std::string abs = assets->assetPath(rel); mat.materialSet = _earth_patch_material_allocator.allocate(device->device(), _earth_patch_material_layout);
std::error_code ec;
if (!abs.empty() && std::filesystem::exists(abs, ec) && !ec) DescriptorWriter writer;
writer.write_buffer(0,
_earth_patch_material_constants_buffer.buffer,
sizeof(GLTFMetallic_Roughness::MaterialConstants),
0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
writer.write_image(1,
checker,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(2,
white,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(3,
flatNormal,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(4,
white,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.write_image(5,
black,
tileSampler,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
writer.update_set(device->device(), mat.materialSet);
if (textures && tileSampler != VK_NULL_HANDLE)
{ {
resolved_path = std::move(abs); const planet::CubeFace face = static_cast<planet::CubeFace>(face_index);
break; const std::string rel = fmt::format("planets/earth/albedo/L0/{}.ktx2", face_legacy(face));
TextureCache::TextureKey tk{};
tk.kind = TextureCache::TextureKey::SourceKind::FilePath;
tk.path = assets->assetPath(rel);
tk.srgb = true;
tk.mipmapped = true;
TextureCache::TextureHandle h = textures->request(tk, tileSampler);
textures->watchBinding(h, mat.materialSet, 1u, tileSampler, checker);
textures->pin(h);
} }
} }
if (!resolved_path.empty())
{
TextureCache::TextureKey tk{};
tk.kind = TextureCache::TextureKey::SourceKind::FilePath;
tk.path = resolved_path;
tk.srgb = true;
tk.mipmapped = true;
TextureCache::TextureHandle h = _context->textures->request(tk, tileSampler);
_context->textures->watchBinding(h, patch.material_instance.materialSet, 1u, tileSampler, checker);
}
} }
} }
@@ -584,6 +596,9 @@ PlanetSystem::EarthPatch *PlanetSystem::get_or_create_earth_patch(const PlanetBo
return nullptr; return nullptr;
} }
const glm::vec4 vertex_color =
_earth_debug_tint_patches_by_lod ? debug_color_for_level(key.level) : glm::vec4(1.0f);
std::vector<Vertex> vertices; std::vector<Vertex> vertices;
const glm::dvec3 patch_center_dir = const glm::dvec3 patch_center_dir =
planet::build_cubesphere_patch_vertices(vertices, planet::build_cubesphere_patch_vertices(vertices,
@@ -593,7 +608,7 @@ PlanetSystem::EarthPatch *PlanetSystem::get_or_create_earth_patch(const PlanetBo
key.x, key.x,
key.y, key.y,
_earth_patch_resolution, _earth_patch_resolution,
debug_color_for_level(key.level)); vertex_color);
if (vertices.empty()) if (vertices.empty())
{ {
@@ -647,8 +662,6 @@ PlanetSystem::EarthPatch *PlanetSystem::get_or_create_earth_patch(const PlanetBo
_earth_patch_lru.push_front(idx); _earth_patch_lru.push_front(idx);
p.lru_it = _earth_patch_lru.begin(); p.lru_it = _earth_patch_lru.begin();
ensure_earth_patch_material_instance(p, earth);
_earth_patch_lookup.emplace(key, idx); _earth_patch_lookup.emplace(key, idx);
return &p; return &p;
} }
@@ -677,7 +690,6 @@ void PlanetSystem::trim_earth_patch_cache()
} }
FrameResources *frame = _context->currentFrame; FrameResources *frame = _context->currentFrame;
TextureCache *textures = _context->textures;
const uint32_t now = _earth_patch_frame_stamp; const uint32_t now = _earth_patch_frame_stamp;
size_t guard = 0; size_t guard = 0;
@@ -712,11 +724,6 @@ void PlanetSystem::trim_earth_patch_cache()
_earth_patch_lru.erase(p.lru_it); _earth_patch_lru.erase(p.lru_it);
_earth_patch_lookup.erase(p.key); _earth_patch_lookup.erase(p.key);
if (textures && p.material_instance.materialSet != VK_NULL_HANDLE)
{
textures->unwatchSet(p.material_instance.materialSet);
}
if (p.vertex_buffer.buffer != VK_NULL_HANDLE) if (p.vertex_buffer.buffer != VK_NULL_HANDLE)
{ {
const AllocatedBuffer vb = p.vertex_buffer; const AllocatedBuffer vb = p.vertex_buffer;
@@ -730,9 +737,7 @@ void PlanetSystem::trim_earth_patch_cache()
} }
} }
const VkDescriptorSet keep_set = p.material_instance.materialSet;
p = EarthPatch{}; p = EarthPatch{};
p.material_instance.materialSet = keep_set;
_earth_patch_free.push_back(idx); _earth_patch_free.push_back(idx);
} }
} }
@@ -755,6 +760,12 @@ void PlanetSystem::update_and_emit(const SceneManager &scene, DrawContext &draw_
PlanetBody *earth = get_body(BodyID::Earth); PlanetBody *earth = get_body(BodyID::Earth);
if (earth && earth->visible && earth->material && _context) if (earth && earth->visible && earth->material && _context)
{ {
if (_earth_patch_cache_dirty)
{
clear_earth_patch_cache();
_earth_patch_cache_dirty = false;
}
const Clock::time_point t0 = Clock::now(); const Clock::time_point t0 = Clock::now();
_earth_quadtree.set_settings(_earth_quadtree_settings); _earth_quadtree.set_settings(_earth_quadtree_settings);
@@ -772,6 +783,17 @@ void PlanetSystem::update_and_emit(const SceneManager &scene, DrawContext &draw_
const Clock::time_point t_q1 = Clock::now(); const Clock::time_point t_q1 = Clock::now();
ensure_earth_patch_index_buffer(); ensure_earth_patch_index_buffer();
ensure_earth_face_materials(*earth);
if (_context->textures)
{
for (const MaterialInstance &mat : _earth_face_materials)
{
if (mat.materialSet != VK_NULL_HANDLE)
{
_context->textures->markSetUsed(mat.materialSet, _context->frameIndex);
}
}
}
size_t desired_capacity = size_t desired_capacity =
static_cast<size_t>(_earth_patches.size()) + static_cast<size_t>(_earth_patches.size()) +
@@ -809,10 +831,6 @@ void PlanetSystem::update_and_emit(const SceneManager &scene, DrawContext &draw_
{ {
patch->last_used_frame = frame_index; patch->last_used_frame = frame_index;
_earth_patch_lru.splice(_earth_patch_lru.begin(), _earth_patch_lru, patch->lru_it); _earth_patch_lru.splice(_earth_patch_lru.begin(), _earth_patch_lru, patch->lru_it);
if (patch->material_instance.materialSet == VK_NULL_HANDLE || patch->material_instance.pipeline == nullptr)
{
ensure_earth_patch_material_instance(*patch, *earth);
}
} }
else else
{ {
@@ -850,14 +868,23 @@ void PlanetSystem::update_and_emit(const SceneManager &scene, DrawContext &draw_
if (patch.state != EarthPatchState::Ready || if (patch.state != EarthPatchState::Ready ||
patch.vertex_buffer.buffer == VK_NULL_HANDLE || patch.vertex_buffer.buffer == VK_NULL_HANDLE ||
patch.vertex_buffer_address == 0 || patch.vertex_buffer_address == 0 ||
patch.material_instance.materialSet == VK_NULL_HANDLE ||
patch.material_instance.pipeline == nullptr ||
_earth_patch_index_buffer.buffer == VK_NULL_HANDLE || _earth_patch_index_buffer.buffer == VK_NULL_HANDLE ||
_earth_patch_index_count == 0) _earth_patch_index_count == 0)
{ {
continue; continue;
} }
const uint32_t face_index = static_cast<uint32_t>(patch.key.face);
if (face_index >= _earth_face_materials.size())
{
continue;
}
MaterialInstance *material = &_earth_face_materials[face_index];
if (material->materialSet == VK_NULL_HANDLE || material->pipeline == nullptr)
{
continue;
}
const WorldVec3 patch_center_world = const WorldVec3 patch_center_world =
earth->center_world + patch.patch_center_dir * earth->radius_m; earth->center_world + patch.patch_center_dir * earth->radius_m;
const glm::vec3 patch_center_local = world_to_local(patch_center_world, origin_world); const glm::vec3 patch_center_local = world_to_local(patch_center_world, origin_world);
@@ -875,7 +902,7 @@ void PlanetSystem::update_and_emit(const SceneManager &scene, DrawContext &draw_
obj.indexBuffer = _earth_patch_index_buffer.buffer; obj.indexBuffer = _earth_patch_index_buffer.buffer;
obj.vertexBuffer = patch.vertex_buffer.buffer; obj.vertexBuffer = patch.vertex_buffer.buffer;
obj.vertexBufferAddress = patch.vertex_buffer_address; obj.vertexBufferAddress = patch.vertex_buffer_address;
obj.material = &patch.material_instance; obj.material = material;
obj.bounds = b; obj.bounds = b;
obj.transform = transform; obj.transform = transform;
// Planet terrain patches are not meaningful RT occluders; skip BLAS/TLAS builds. // Planet terrain patches are not meaningful RT occluders; skip BLAS/TLAS builds.

View File

@@ -5,6 +5,7 @@
#include <scene/planet/planet_quadtree.h> #include <scene/planet/planet_quadtree.h>
#include <cstdint> #include <cstdint>
#include <array>
#include <list> #include <list>
#include <memory> #include <memory>
#include <string> #include <string>
@@ -75,6 +76,9 @@ public:
uint32_t earth_patch_cache_max() const { return _earth_patch_cache_max; } uint32_t earth_patch_cache_max() const { return _earth_patch_cache_max; }
void set_earth_patch_cache_max(uint32_t max_patches) { _earth_patch_cache_max = max_patches; } void set_earth_patch_cache_max(uint32_t max_patches) { _earth_patch_cache_max = max_patches; }
bool earth_debug_tint_patches_by_lod() const { return _earth_debug_tint_patches_by_lod; }
void set_earth_debug_tint_patches_by_lod(bool enabled);
private: private:
enum class EarthPatchState : uint8_t enum class EarthPatchState : uint8_t
{ {
@@ -90,8 +94,6 @@ private:
AllocatedBuffer vertex_buffer{}; AllocatedBuffer vertex_buffer{};
VkDeviceAddress vertex_buffer_address = 0; VkDeviceAddress vertex_buffer_address = 0;
MaterialInstance material_instance{};
glm::vec3 bounds_origin{0.0f}; glm::vec3 bounds_origin{0.0f};
glm::vec3 bounds_extents{0.5f}; glm::vec3 bounds_extents{0.5f};
float bounds_sphere_radius = 0.5f; float bounds_sphere_radius = 0.5f;
@@ -109,7 +111,8 @@ private:
void ensure_earth_patch_index_buffer(); void ensure_earth_patch_index_buffer();
void ensure_earth_patch_material_layout(); void ensure_earth_patch_material_layout();
void ensure_earth_patch_material_constants_buffer(); void ensure_earth_patch_material_constants_buffer();
void ensure_earth_patch_material_instance(EarthPatch &patch, const PlanetBody &earth); void ensure_earth_face_materials(const PlanetBody &earth);
void clear_earth_patch_cache();
void trim_earth_patch_cache(); void trim_earth_patch_cache();
EngineContext *_context = nullptr; EngineContext *_context = nullptr;
@@ -132,10 +135,14 @@ private:
DescriptorAllocatorGrowable _earth_patch_material_allocator{}; DescriptorAllocatorGrowable _earth_patch_material_allocator{};
bool _earth_patch_material_allocator_initialized = false; bool _earth_patch_material_allocator_initialized = false;
AllocatedBuffer _earth_patch_material_constants_buffer{}; AllocatedBuffer _earth_patch_material_constants_buffer{};
std::array<MaterialInstance, 6> _earth_face_materials{};
uint32_t _earth_patch_frame_stamp = 0; uint32_t _earth_patch_frame_stamp = 0;
uint32_t _earth_patch_resolution = 33; uint32_t _earth_patch_resolution = 33;
uint32_t _earth_patch_create_budget_per_frame = 16; uint32_t _earth_patch_create_budget_per_frame = 16;
float _earth_patch_create_budget_ms = 2.0f; float _earth_patch_create_budget_ms = 2.0f;
uint32_t _earth_patch_cache_max = 2048; uint32_t _earth_patch_cache_max = 2048;
bool _earth_debug_tint_patches_by_lod = false;
bool _earth_patch_cache_dirty = false;
}; };