ADD: async glTF texture preloading

This commit is contained in:
2025-12-04 16:19:53 +09:00
parent 73e15ee456
commit 017c02e8d7
5 changed files with 50 additions and 1 deletions

View File

@@ -206,7 +206,7 @@ void VulkanEngine::init()
// Async asset loader for background glTF + texture jobs // Async asset loader for background glTF + texture jobs
_asyncLoader = std::make_unique<AsyncAssetLoader>(); _asyncLoader = std::make_unique<AsyncAssetLoader>();
_asyncLoader->init(this, _assetManager.get(), _textureCache.get(), 1); _asyncLoader->init(this, _assetManager.get(), _textureCache.get(), 4);
// Optional ray tracing manager if supported and extensions enabled // Optional ray tracing manager if supported and extensions enabled
if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure()) if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure())
@@ -342,6 +342,7 @@ void VulkanEngine::init_default_data()
} }
addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f)); addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f));
preloadInstanceTextures("mirage");
_mainDeletionQueue.push_function([&]() { _mainDeletionQueue.push_function([&]() {
_resourceManager->destroy_image(_whiteImage); _resourceManager->destroy_image(_whiteImage);
@@ -391,6 +392,36 @@ uint32_t VulkanEngine::loadGLTFAsync(const std::string &sceneName,
return _asyncLoader->load_gltf_async(sceneName, modelRelativePath, transform); return _asyncLoader->load_gltf_async(sceneName, modelRelativePath, transform);
} }
void VulkanEngine::preloadInstanceTextures(const std::string &instanceName)
{
if (!_textureCache || !_sceneManager)
{
return;
}
auto gltfScene = _sceneManager->getGLTFInstanceScene(instanceName);
if (!gltfScene)
{
return;
}
uint32_t frame = static_cast<uint32_t>(_frameNumber);
uint32_t count = 0;
// Mark all materials in this glTF scene as used so TextureCache will
// schedule their textures for upload before the object is visible.
for (const auto &[name, material] : gltfScene->materials)
{
if (material && material->data.materialSet)
{
_textureCache->markSetUsed(material->data.materialSet, frame);
++count;
}
}
fmt::println("[Engine] Preloaded {} material sets for instance '{}'", count, instanceName);
}
void VulkanEngine::cleanup() void VulkanEngine::cleanup()
{ {
if (_asyncLoader) if (_asyncLoader)

View File

@@ -210,6 +210,10 @@ public:
const std::string &modelRelativePath, const std::string &modelRelativePath,
const glm::mat4 &transform = glm::mat4(1.f)); const glm::mat4 &transform = glm::mat4(1.f));
// Preload textures for an already-loaded scene instance so they are
// available before the object becomes visible (visibility-driven loading).
void preloadInstanceTextures(const std::string &instanceName);
bool resize_requested{false}; bool resize_requested{false};
bool freeze_rendering{false}; bool freeze_rendering{false};

View File

@@ -467,6 +467,7 @@ namespace
glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(gltfScale[0], gltfScale[1], gltfScale[2])); glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(gltfScale[0], gltfScale[1], gltfScale[2]));
glm::mat4 M = T * R * S; glm::mat4 M = T * R * S;
eng->loadGLTFAsync(gltfName, gltfPath, M); eng->loadGLTFAsync(gltfName, gltfPath, M);
eng->preloadInstanceTextures(gltfName);
} }
} }

View File

@@ -518,6 +518,16 @@ bool SceneManager::removeGLTFInstance(const std::string &name)
return true; return true;
} }
std::shared_ptr<LoadedGLTF> SceneManager::getGLTFInstanceScene(const std::string &instanceName) const
{
auto it = dynamicGLTFInstances.find(instanceName);
if (it != dynamicGLTFInstances.end())
{
return it->second.scene;
}
return nullptr;
}
bool SceneManager::getGLTFInstanceTransform(const std::string &name, glm::mat4 &outTransform) bool SceneManager::getGLTFInstanceTransform(const std::string &name, glm::mat4 &outTransform)
{ {
auto it = dynamicGLTFInstances.find(name); auto it = dynamicGLTFInstances.find(name);

View File

@@ -177,6 +177,9 @@ public:
const PickingDebug &getPickingDebug() const { return pickingDebug; } const PickingDebug &getPickingDebug() const { return pickingDebug; }
// Returns the LoadedGLTF scene for a named GLTF instance, or nullptr if not found.
std::shared_ptr<LoadedGLTF> getGLTFInstanceScene(const std::string &instanceName) const;
private: private:
EngineContext *_context = nullptr; EngineContext *_context = nullptr;