材质与环境光照:UE 打包 Specular 导入(R=AO/G=Rough/B=Metal 与 glTF MR 同序 → 同一贴图直供 MetallicRoughness + Ao 槽,factors 直用贴图,默认置翻绿位 misc.w);MappedNormal 支持 DirectX 法线翻绿(misc.w,编辑器加 Flip Green 开关);环境遮蔽拆分漫反射与高光(高光遮蔽更狠:室内高光须压暗,此前表面反射天空贴图 = 室内穿帮);ufbx 导入日志补齐 mr/normal/ao/emissive 槽位

This commit is contained in:
2026-10-18 15:23:07 +08:00
parent e7711134fe
commit 22309d24f0
4 changed files with 60 additions and 10 deletions
+37 -4
View File
@@ -288,12 +288,45 @@ namespace {
dst.texPaths[Material::Albedo] =
ResolveUfbxTexture(modelDir, *base.texture);
}
// UE/ORCA 打包 Specular 工作流:R=AO, G=Roughness, B=Metalness。
// 通道与 glTF MR 合图(G=rough, B=metal)恰好同序 → 同一张贴图
// 直供 MetallicRoughness 槽 + Ao 槽,纹理缓存按路径去重共享同一
// Texture*。factors=(1,1,0,0):金属/粗糙因子直用贴图(z=0 → shader
// 读 MR.g 当粗糙度,同 glTF 语义)。UE 打包 Specular ⇔ DirectX
// 法线(同源约定)→ 默认置翻绿位 misc.w
if (const ufbx_material_map& spec = mat->pbr.specular_color;
spec.texture != nullptr) {
const std::string p =
ResolveUfbxTexture(modelDir, *spec.texture);
dst.texPaths[Material::MetallicRoughness] = p;
dst.texPaths[Material::Ao] = p;
dst.params.factors = glm::vec4(1.0f, 1.0f, 0.0f, 0.0f);
dst.params.misc.w = 1.0f;
}
if (const ufbx_material_map& nrm = mat->pbr.normal_map;
nrm.texture != nullptr) {
dst.texPaths[Material::Normal] =
ResolveUfbxTexture(modelDir, *nrm.texture);
}
if (const ufbx_material_map& emi = mat->pbr.emission_color;
emi.texture != nullptr) {
dst.texPaths[Material::Emissive] =
ResolveUfbxTexture(modelDir, *emi.texture);
}
ENGINE_INFO(
"ufbx Mesh '{}': Material '{}': albedo={}", dst.name,
mat->name.length ? U8Str(mat->name) : "?",
"ufbx Mesh '{}': Material '{}': albedo={} mr={} normal={} ao={} emissive={}",
dst.name, mat->name.length ? U8Str(mat->name) : "?",
dst.texPaths[Material::Albedo].empty()
? "<none>"
: dst.texPaths[Material::Albedo]);
? "<none>" : dst.texPaths[Material::Albedo],
dst.texPaths[Material::MetallicRoughness].empty()
? "<none>" : dst.texPaths[Material::MetallicRoughness],
dst.texPaths[Material::Normal].empty()
? "<none>" : dst.texPaths[Material::Normal],
dst.texPaths[Material::Ao].empty()
? "<none>" : dst.texPaths[Material::Ao],
dst.texPaths[Material::Emissive].empty()
? "<none>" : dst.texPaths[Material::Emissive]);
};
std::unordered_map<std::string, u32> boneSlots;