Unity2021.3.21默认法线贴图显示Bug
Unity2021.3.21默认法线贴图显示Bug
Unity2021.3.21默认法线贴图显示Bug
00 背景说明
在 Unity 着色器中, 如果声明了法线贴图却未赋值, 系统会自动使用内置的“UnityNormalMap”进行替代采样. Unity 支持两种法线贴图编码模式, 可在 Player Settings 中切换:
- XYZ
- DXT5nm-style(移动端以外平台的默认模式, 质量较高但解码开销更大)
在 Unity 2021.3.21f1 版本中, 将 Editor 平台切换至 Android 后, 法线贴图编码(Unity的法线贴图编码模式可以在PlayerSetting中设置, 有XYZ与DXT5nm-style)仍会保持为 DXT5nm-style.
关于DXT5nm-style的说明
DXT5nm-style法线贴图编码.
这是非移动平台上的默认法线贴图编码方式.
相较于NormalMapEncoding.XYZ, 此类法线贴图质量更高, 但在着色器中解码时计算成本更高.
简单来说, 质量可能更高, 但GPU消耗更大.
01 Bug描述
触发环境
- 引擎版本: Unity 2021.3.21f1(及之前版本)
- 平台设置: Android
- 法线贴图编码: DXT5nm-style
- 编辑器渲染: 默认 DX11
复现步骤
- 创建一份简单着色器(手写或 Shader Graph 均可).
- 在着色器中声明法线贴图, 默认值设为
"bump", 并生成材质. - 将该材质赋予场景中的物体, 同时保持法线贴图留空.
- 在满足上述环境条件时, 即可观察到法线贴图无效或异常效果.
02 原因分析
Unity 内置的“UnityNormalMap”始终以 RGBA32 格式存储, 不会随法线贴图编码设置而自动转换;而采样器则会根据平台及编码模式切换采样逻辑, 导致使用默认纹理时格式不匹配, 从而引发显示错误.
03 解决方案
- 升级引擎 将 Unity 升至 2021.3.45f1 或更高版本, 该版本已修复此问题.
- 强制使用 GLES 渲染 在 GLES 模式下不会出现上述异常, 但可能对部分项目兼容性产生影响.
- 修改法线贴图编码(推荐) 将法线贴图编码切换为
XYZ:- 可彻底避免该 Bug;
- 降低 GPU 解码开销;
- 虽然会略微降低法线精度, 但在视觉效果上并不明显, 且对美术工作流程更友好.
- 强制使用OpenGLES渲染方式
- 在UnityHub的对应工程启动参数中添加
-force-gles
- 在UnityHub的对应工程启动参数中添加
参考网页
本文由作者按照 CC BY 4.0 进行授权


