材质与环境光照: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
+11 -5
View File
@@ -45,7 +45,7 @@ layout(set = 1, binding = 6) uniform MaterialParams {
vec4 factors; // x = metallic 因子,y = roughness 因子,z = 独立粗糙度图开关,w = MASK 镂空开关
vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度
vec4 surface; // x = ior(F0 换算),y = transmission(不透明段恒 0 语义),z = 自发光强度,w = 体积厚度
vec4 misc; // x = unlit(KHR_materials_unlit,1 = 早退直出 albedo),y = UV 左右镜像,z = UV 上下镜像
vec4 misc; // x = unlit(KHR_materials_unlit,1 = 早退直出 albedo),y = UV 左右镜像,z = UV 上下镜像,w = 法线绿通道翻转(DirectX)
vec4 emissiveFactor; // 自发光颜色(rgb × emissiveMap × surface.z;黑 = 不发光)
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22),槽序 = binding
vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0)
@@ -124,6 +124,8 @@ vec3 MappedNormal(vec3 geomN, vec3 T, vec2 uv) {
vec3 nT = normalize(T - N * dot(N, T)); // 正交化
vec3 B = cross(N, nT);
vec3 sampled = texture(normalMap, uv).xyz * 2.0 - 1.0;
// DirectX 法线(绿通道朝下)→ OpenGL:翻绿。UE 打包 Specular 资产默认开
if (matParams.misc.w > 0.5) sampled.y = -sampled.y;
if (dot(sampled, sampled) < 1e-4) return geomN;
return normalize(nT * sampled.x + B * sampled.y + N * sampled.z);
@@ -257,17 +259,21 @@ void main() {
vec3 irradiance = texture(irradianceMap, N).rgb;
float ao = texture(aoMap, ApplyUv(4, fragUV)).r;
vec3 diffuse = kD_amb * irradiance * albedo * ao;
// 漫反射环境遮蔽:材料 AO × 阴影软化(较温和,保留阴影内可读性)
float diffOcc = ao * mix(0.4, 1.0, shade0);
vec3 diffuse = kD_amb * irradiance * albedo * diffOcc;
vec3 R = reflect(-V, N);
const float kMaxPrefilterMip = 4.0; // 与 Cubemap::kPrefilterMips - 1 同步
vec3 prefilteredColor = textureLod(prefilteredMap, R,
roughness * kMaxPrefilterMip).rgb;
vec2 envBRDF = texture(brdfLut, vec2(NdotV, roughness)).rg;
vec3 specular = prefilteredColor * (F_amb * envBRDF.x + envBRDF.y);
// 高光遮蔽(specular occlusion):比漫反射更狠——室内环境高光必须压暗,
// 否则室内表面反射出天空贴图(穿帮根因)
float specOcc = ao * mix(0.12, 1.0, shade0);
vec3 specular = prefilteredColor * (F_amb * envBRDF.x + envBRDF.y) * specOcc;
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb
* mix(0.4, 1.0, shade0); // 阴影区环境同步衰减(简化遮蔽)
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb;
// 不透明段覆盖率恒 1:本 pass 只画 alphaMode=OPAQUE/MASK 表面,像素必
// 被完全覆盖。绝不能拿 albedo 贴图 alpha 当覆盖率——HI3/Genshin 脸部