FIX: AO/Emissive loading fix

This commit is contained in:
2025-12-05 16:54:00 +09:00
parent 28572c1679
commit 20f6ad494c
5 changed files with 64 additions and 13 deletions

View File

@@ -220,8 +220,28 @@ std::shared_ptr<MeshAsset> AssetManager::createMesh(const MeshCreateInfo &info)
{
const auto &opt = info.material.options;
// Fallbacks are bound now; real textures will patch in via TextureCache
AllocatedBuffer matBuffer = createMaterialBufferWithConstants(opt.constants);
GLTFMetallic_Roughness::MaterialConstants constants = opt.constants;
if (!opt.occlusionPath.empty())
{
if (constants.extra[0].y == 0.0f && constants.extra[0].z == 0.0f)
{
constants.extra[0].y = 1.0f; // AO strength
constants.extra[0].z = 1.0f; // hasAO flag
}
}
if (!opt.emissivePath.empty())
{
if (constants.extra[1].x == 0.0f &&
constants.extra[1].y == 0.0f &&
constants.extra[1].z == 0.0f)
{
constants.extra[1] = glm::vec4(1.0f, 1.0f, 1.0f, constants.extra[1].w);
}
}
AllocatedBuffer matBuffer = createMaterialBufferWithConstants(constants);
GLTFMetallic_Roughness::MaterialResources res{};
res.colorImage = _engine->_errorCheckerboardImage;
@@ -519,10 +539,6 @@ AllocatedBuffer AssetManager::createMaterialBufferWithConstants(
{
matConstants->extra[0].x = 1.0f; // normal scale default
}
if (matConstants->extra[0].y == 0.0f)
{
matConstants->extra[0].y = 1.0f;
}
// Ensure writes are visible on non-coherent memory
vmaFlushAllocation(_engine->_deviceManager->allocator(), matBuffer.allocation, 0,
sizeof(GLTFMetallic_Roughness::MaterialConstants));

View File

@@ -91,12 +91,12 @@ void GeometryPass::register_graph(RenderGraph *graph,
builder.write_color(gbufferPosition, true, clear);
builder.write_color(gbufferNormal, true, clear);
builder.write_color(gbufferAlbedo, true, clear);
VkClearValue clearExtra{};
clearExtra.color = {{1.f, 0.f, 0.f, 0.f}}; // AO=1, emissive=0
builder.write_color(gbufferExtra, true, clearExtra);
VkClearValue clearID{};
clearID.color.uint32[0] = 0u;
builder.write_color(idHandle, true, clearID);
VkClearValue clearExtra{};
clearExtra.color = {{1.f, 0.f, 0.f, 0.f}}; // AO=1, emissive=0
builder.write_color(gbufferExtra, true, clearExtra);
// Reverse-Z: clear depth to 0.0
VkClearValue depthClear{};

View File

@@ -389,12 +389,35 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine,
constants.metal_rough_factors.y = mat.pbrData.roughnessFactor;
// extra[0].x: normalScale (default 1.0)
constants.extra[0].x = 1.0f;
// extra[0].y: occlusionStrength (0..1, default 1.0)
constants.extra[0].y = mat.occlusionTexture.has_value() ? mat.occlusionTexture->strength : 1.0f;
// extra[0].y: occlusionStrength (0..1)
// extra[0].z: hasAO flag (1.0 if an occlusionTexture is present, 0.0 otherwise)
if (mat.occlusionTexture.has_value())
{
constants.extra[0].y = mat.occlusionTexture->strength;
constants.extra[0].z = 1.0f;
}
else
{
constants.extra[0].y = 0.0f;
constants.extra[0].z = 0.0f;
}
// extra[1].rgb: emissiveFactor
constants.extra[1].x = mat.emissiveFactor[0];
constants.extra[1].y = mat.emissiveFactor[1];
constants.extra[1].z = mat.emissiveFactor[2];
// If an emissive texture is present but the factor is left at 0,
// default to white so the texture is visible (common authoring pattern).
if (mat.emissiveTexture.has_value())
{
if (constants.extra[1].x == 0.0f &&
constants.extra[1].y == 0.0f &&
constants.extra[1].z == 0.0f)
{
constants.extra[1].x = 1.0f;
constants.extra[1].y = 1.0f;
constants.extra[1].z = 1.0f;
}
}
// extra[2].x: alphaCutoff for MASK materials (>0 enables alpha test)
constants.extra[2].x = 0.0f;
if (mat.alphaMode == fastgltf::AlphaMode::Mask)