Improve PBR quality: mip chains, anisotropic filtering, baseColorFactor
Root causes behind blurry/unphysical materials (4K pocket watch render mushy, glass fully opaque, watch hands unreadable): - Textures loaded via stbi had a single mip level: 4096x4096 albedo/MR maps sampled with no LOD -> minification aliasing turned fine detail (watch hands) into noise. Generate a full blit-based mip chain with per-level layout transitions. - samplerAnisotropy was never enabled on the device and every sampler was created with anisotropy disabled: grazing-angle surfaces (watch face, ground) collapsed into a blur. Enable the device feature and 16x anisotropic filtering on material texture samplers. - glTF baseColorFactor was ignored: the glass material (alphaMode BLEND, no baseColor texture, baseColorFactor.a = 0.3) fell back to the default white texture with alpha = 1 and rendered fully opaque. MaterialParams gains a baseColor vec4 (rgb tints albedo, a scales the blend alpha) threaded through both PBR shaders. - alphaMode MASK was treated as opaque: add a factors.w switch that performs an alpha cutout test in the opaque shader. - Fix material cache key dropping factors.z (separate-roughness switch); it now encodes the full factors and baseColor vectors.
This commit is contained in:
@@ -695,12 +695,27 @@ ParsedMesh Model::ProcessMesh(const aiMesh* mesh, const aiScene* scene,
|
||||
params.factors = glm::vec4(static_cast<f32>(metallic),
|
||||
static_cast<f32>(roughness), 0.0f, 0.0f);
|
||||
|
||||
// glTF alphaMode:BLEND = 半透明(透明绘制队列 + 深度只测不写)。
|
||||
// MASK(alpha cutout)暂按不透明——需要 alpha test,后续演进。
|
||||
// baseColorFactor:rgb 调色进 albedo;a 是 BLEND 材质的透明度
|
||||
//(玻璃等无 baseColor 贴图、纯靠 factor alpha 的材质全靠它,
|
||||
// 缺了会退化成兜底白纹理的 a=1 = 完全不透)
|
||||
aiColor4D baseColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (material->Get(AI_MATKEY_BASE_COLOR, baseColor) == AI_SUCCESS) {
|
||||
params.baseColor = glm::vec4(baseColor.r, baseColor.g,
|
||||
baseColor.b, baseColor.a);
|
||||
}
|
||||
|
||||
// glTF alphaMode:
|
||||
// BLEND = 半透明(透明绘制队列 + 深度只测不写)
|
||||
// MASK = 镂空(factors.w=1 → shader 侧 alpha test 丢弃,
|
||||
// 表针/栅栏等硬边贴图常见)仍走不透明队列
|
||||
// OBJ/FBX 无此键 → 恒不透明(资产格式定义写死)
|
||||
aiString alphaMode;
|
||||
if (material->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
|
||||
out.transparent = (alphaMode == aiString("BLEND"));
|
||||
if (alphaMode == aiString("BLEND")) {
|
||||
out.transparent = true;
|
||||
} else if (alphaMode == aiString("MASK")) {
|
||||
params.factors.w = 1.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FBX/OBJ 独立贴图工作流
|
||||
|
||||
Reference in New Issue
Block a user