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
_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
if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure())
@@ -342,6 +342,7 @@ void VulkanEngine::init_default_data()
}
addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f));
preloadInstanceTextures("mirage");
_mainDeletionQueue.push_function([&]() {
_resourceManager->destroy_image(_whiteImage);
@@ -391,6 +392,36 @@ uint32_t VulkanEngine::loadGLTFAsync(const std::string &sceneName,
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()
{
if (_asyncLoader)

View File

@@ -210,6 +210,10 @@ public:
const std::string &modelRelativePath,
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 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 M = T * R * S;
eng->loadGLTFAsync(gltfName, gltfPath, M);
eng->preloadInstanceTextures(gltfName);
}
}

View File

@@ -518,6 +518,16 @@ bool SceneManager::removeGLTFInstance(const std::string &name)
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)
{
auto it = dynamicGLTFInstances.find(name);

View File

@@ -177,6 +177,9 @@ public:
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:
EngineContext *_context = nullptr;