当前位置: 首页 > news >正文

Unity URP 法线贴图如何生成 用什么工具创建

从零理解法线贴图的原理,掌握从 Photoshop、Blender 到 Substance 的多种生成工具,并在 URP 管线中正确实现法线贴图的采样与光照计算。

一、什么是法线贴图

法线贴图(Normal Map)是一种特殊的纹理,它不存储颜色信息,而是逐像素地编码了表面的法线方向。在渲染时,GPU 读取法线贴图中的法线向量,替代模型原本的顶点插值法线,从而在不增加几何复杂度的情况下模拟出丰富的表面凹凸细节。

核心要点:法线贴图通过在像素着色器中逐片元替换表面法线,让光线在"假凹凸"上产生正确的反射方向。眼睛看到的是细节,而三角形数量并没有增加。这是现代实时渲染中最重要的"障眼法"之一。

二、法线贴图的工作原理

2.1 切线空间(Tangent Space)

绝大多数的法线贴图都使用切线空间。切线空间是一个以模型表面为参考的局部坐标系,由三个正交轴构成:

  • T(Tangent)— 切线方向,沿 UV 的 U 轴方向
  • B(Bitangent / Binormal)— 副切线方向,沿 UV 的 V 轴方向
  • N(Normal)— 顶点法线方向,垂直于表面

在切线空间中,一个完全平坦的表面法线是(0, 0, 1),在法线贴图中的颜色就是(128, 128, 255)即浅蓝色。这就是为什么法线贴图整体看起来偏蓝。

2.2 解码公式

在着色器中,法线贴图的采样值从[0, 1]范围映射到[-1, 1]

// 从法线贴图采样得到的颜色值 (0~1) float4 normalTex = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, IN.uv); // 解码:从 [0,1] 映射到 [-1,1] float3 tangentNormal = normalTex.xyz * 2.0 - 1.0; // 或者使用 Unity 内置函数(处理 DXT5nm 压缩格式) float3 tangentNormal = UnpackNormal(normalTex);

注意 DXT5nm 压缩:使用UnpackNormal()是最安全的做法。Unity 在构建时可能将法线贴图压缩为 DXT5nm 格式,此时 R 通道被丢弃,法线的 X 存于 A 通道,Y 存于 G 通道。直接* 2 - 1会得到错误结果。

三、工具矩阵:用什么生成法线贴图

创建法线贴图主要有两条路径:从 2D 纹理转换(高度图 → 法线贴图),和从高模烘焙到低模。下面逐一介绍主流工具。

四、工具推荐对比

工具类型价格上手难度推荐场景
Substance Designer2D 节点式$$$专业程序化纹理制作
Substance Painter高模烘焙$$$中高3D 资产纹理绘制
Blender Bake高模烘焙免费独立开发者、预算有限
Photoshop2D 滤镜$$快速转换、UI 纹理
NormalMap-Online在线 2D免费极低快速原型、学习测试
xNormal高模烘焙免费轻量专业烘焙
Materialize2D 转换免费从照片生成 PBR 材质

五、实战:用 Photoshop 从高度图生成法线贴图

这是最快捷的创建方式,适合有现成高度图或灰度纹理的场景。

  1. 准备高度图

    准备一张灰度图。白色 = 凸起(最高),黑色 = 凹陷(最低)。确保图片是 2 的幂尺寸(512、1024、2048 等),这是 GPU 纹理的基本要求。

  2. 应用法线贴图滤镜

    打开 Photoshop → 菜单栏 →滤镜 → 3D → 生成法线贴图(Filter → 3D → Generate Normal Map)。如果没有 3D 菜单,检查首选项中是否启用了图形处理器。

  3. 调节参数

    在弹出的对话框中调节以下关键参数:模糊(Blur)一般设为 0~1 避免细节丢失;细节缩放(Detail Scale)控制凹凸强度,默认 10,砖墙类可调至 15~20;反转 Y— Unity 使用 OpenGL 法线格式(Y+ 向上),确保不勾选 Invert Y。

  4. 保存并导入 Unity

    导出为 PNG 或 TGA。导入 Unity 后,在 Inspector 中将纹理类型设为Normal Map,勾选Create from Grayscale如果还没做法线转换。确保 Texture Shape 为 2D。

六、实战:用 Blender 从高模烘焙法线贴图

这是游戏资产制作的黄金标准流程,适合已有高模雕刻和低模拓扑的场景。

  1. 准备高低模

    低模:正确展开 UV、所有面朝外、面法线方向一致。高模:雕刻好细节,与低模对齐位置。两个模型应重叠在同一世界位置。

  2. 创建烘焙用材质

    选中低模,在 Shader Editor 中新建一个 Image Texture 节点,新建一张图片(如 2048×2048),保持该节点选中状态(橙色高亮边框)。这是关键一步,烘焙结果就输出到这个节点。

  3. 配置烘焙参数

    Render Properties → Bake → Bake Type 选择Normal。关键参数:Extrusion(挤出距离/ Cage)— 设为 0.01~0.05m 防止漏烘;Max Ray Distance— 通常 0.1m 足够;Space 保持Tangent

  4. 先选高模再选低模

    在 Object Mode 下先选中高模,然后 Shift 加选低模(低模为最后选中 = Active)。顺序不能错。

  5. 执行烘焙

    点击Bake按钮,等待完成。完成后在 UV Editor 中查看结果:蓝色为主色调,细节处有红绿变化,即表示成功。

  6. 导出

    Image → Save As → 导出为 PNG。导入 Unity,Texture Type 设为Normal Map

七、在 URP 中使用法线贴图

7.1 Unity URP Lit Shader

使用 URP 内置的 Lit Shader 是最简单的方式。将生成的法线贴图拖入材质的Normal Map槽位即可。URP Lit 内部已经完成了 TBN 矩阵构建、采样、解码和光照计算的全流程。

7.2 材质参数说明

参数作用建议值
Normal Map法线贴图纹理导入的 PNG/TGA
Normal Scale法线强度系数 (0~1)0.5~1.0,默认 1.0
Base Map基础颜色(Albedo)对应的漫反射贴图
Smoothness表面光滑度0.3~0.7(多数非金属)
Metallic金属度0(非金属)或 1(金属)

7.3 手动编写 URP 法线贴图 Shader

如果需要自定义光照或特殊效果,可以手写 Shader。以下是一个完整的 URP 法线贴图片段着色器:

Shader "Custom/URP_NormalLit" { Properties { _BaseMap("Base Map", 2D) = "white" {} _BaseColor("Base Color", Color) = (1,1,1,1) _NormalMap("Normal Map", 2D) = "bump" {} _NormalScale("Normal Scale", Range(0,2)) = 1 _Smoothness("Smoothness", Range(0,1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } Pass { Name "ForwardLit" Tags { "LightMode"="UniversalForward" } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 positionWS : TEXCOORD1; float3 normalWS : TEXCOORD2; float4 tangentWS : TEXCOORD3; }; TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseColor; float4 _NormalMap_ST; float _NormalScale; float _Smoothness; CBUFFER_END Varyings vert(Attributes IN) { Varyings OUT; OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz); OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS); OUT.tangentWS = float4( TransformObjectToWorldDir(IN.tangentOS.xyz), IN.tangentOS.w); OUT.uv = IN.uv; return OUT; } float4 frag(Varyings IN) : SV_Target { // 采样基底色 float4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); float3 albedo = baseMap.rgb * _BaseColor.rgb; // 采样并解码切线空间法线 float4 normalTex = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, IN.uv); float3 tangentNormal = UnpackNormalScale(normalTex, _NormalScale); // 构建 TBN 矩阵,将法线从切线空间转换到世界空间 float3 N = normalize(IN.normalWS); float3 T = normalize(IN.tangentWS.xyz); float3 B = normalize(cross(N, T) * IN.tangentWS.w); float3x3 TBN = float3x3(T, B, N); float3 worldNormal = normalize(mul(tangentNormal, TBN)); // URP 主光照计算 Light mainLight = GetMainLight(); float NdotL = saturate(dot(worldNormal, mainLight.direction)); float3 diffuse = albedo * mainLight.color * NdotL; // 环境光 float3 ambient = SampleSH(worldNormal) * albedo; // 简易高光(Blinn-Phong) float3 viewDir = GetWorldSpaceViewDir(IN.positionWS); float3 halfDir = SafeNormalize(mainLight.direction + viewDir); float spec = pow(saturate(dot(worldNormal, halfDir)), 32.0); float3 specular = mainLight.color * spec * _Smoothness; return float4(diffuse + ambient + specular, 1.0); } ENDHLSL } } }

代码关键步骤:
UnpackNormalScale()— 解码法线贴图并乘以缩放系数
TBN 矩阵— 由世界空间的 T、B、N 三向量构建,将切线空间法线转换到世界空间
GetMainLight()— URP 内置函数,获取场景主方向光

八、常见问题与解决方案

问题 1:法线贴图导入后显示为灰色而非蓝色
原因:Unity 没有识别为法线贴图。
解决:Inspector 中将Texture Type设为Normal Map

问题 2:凹凸方向反了(凸的变凹)
原因:法线贴图的 Y 通道方向与 Unity 不匹配。Unity 使用 OpenGL 标准(Y+ = 向上),如果你的贴图是 DirectX 标准(Y+ = 向下),需要反转。
解决:在法线贴图的 Inspector 中勾选Flip Y Channel,或在 Photoshop 生成时不勾选 Invert Y。

问题 3:法线贴图在某些面上看起来是黑的
原因:模型的某些面法线方向反了,或者 UV 镜像导致切线空间的 winding order 不一致。
解决:检查模型面法线方向(Blender:Shift+N重新计算)、确保 UV 无镜像重叠。

问题 4:使用 UnpackNormal 报错
原因:没有包含正确的头文件。
解决:确保 include 了Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl

九、法线贴图的纹理导入设置

在 Unity 中正确导入法线贴图至关重要。以下是在 Inspector 中的推荐设置:

设置项推荐值说明
Texture TypeNormal Map必须设置,Unity 才会正确解码
Texture Shape2D标准 2D 纹理
sRGB (Color Texture)❌ 取消勾选法线贴图是数据纹理,不是颜色纹理,必须线性空间
Non-Power of 2ToNearest非 2 的幂尺寸自动缩放
CompressionNormal Quality / High Quality选择 Normal 压缩以使用 DXT5nm
Max Size2048 或根据需求多数情况 1024 或 2048 足够
Generate Mip Maps✅ 勾选生成多级渐远纹理,避免远处摩尔纹

关键:关闭 sRGB。法线贴图存储的是方向数据而非颜色数据。勾选 sRGB 会导致 Gamma 校正被应用到法线值上,使法线方向偏移,产生错误的光照结果。这是最常见的导入错误。

十、总结与最佳实践

  • 选对工具:简单转换用 Photoshop 或 NormalMap-Online;专业资产用 Substance Painter 烘焙;预算有限用 Blender。
  • 关闭 sRGB:法线贴图导入 Unity 后务必取消 sRGB 勾选。
  • 使用 UnpackNormal:永远用UnpackNormal()UnpackNormalScale()解码,不要手动*2-1
  • 注意 Y 轴方向:Unity 使用 OpenGL 法线格式(Y+ 向上),确保生成工具的输出格式匹配。
  • 法线贴图尺寸:通常 1024 或 2048 足够,过高分辨率对移动端性能影响显著。
  • 配合其他贴图:法线贴图与粗糙度贴图(Roughness)、AO 贴图配合使用,能产生更真实的材质效果。
  • 移动端优化:如果目标平台是移动端,考虑使用 ASTC 压缩格式,并在低端设备上将法线贴图降到 512。
http://www.jsqmd.com/news/1002141/

相关文章:

  • 流体智能体强化学习:动态群体协作的新范式
  • 3分钟上手:英雄联盟玩家的智能游戏助手完全指南
  • MC9S08GT系列8位MCU:低功耗架构与丰富外设的嵌入式经典设计解析
  • AI 驱动的会议效率提升:从语音转写到行动项提取的工程实践
  • Zotero GPT终极指南:如何用AI智能插件5分钟打造高效文献助手
  • 2026年上海松江区权威金条回收+银条回收机构推荐:称重准 报价实 - 沪上贵金属口碑推荐官
  • 5分钟解决日文游戏乱码:Locale-Emulator终极配置指南
  • 儿童增高床垫品牌哪家好?自己用过才敢说 - 深圳市民HLL
  • Kemono下载器:Windows平台终极批量下载解决方案
  • 56800TDC开发套件实战指南:从硬件安装到CodeWarrior环境搭建
  • 上海嘉定区金条回收别乱找!2026公认靠谱的机构都在这 - 沪上贵金属口碑推荐官
  • 【毕业设计】基于 SpringBoot 的个性化旅游行程规划系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 68HC908LJ12深度解析:8位MCU的Flash管理与低功耗设计实战
  • 嵌入式安全实践:基于IEC 60730标准的MCU硬件特性与软件自检设计
  • 汽车电子MCU选型与开发实战:MPC5646C架构解析与应用指南
  • 南京日语培训班哪家强 2026年实力机构选择参考 - 品牌排行榜
  • 别再死记硬背了!用Wireshark抓包实战,帮你彻底搞懂TCP确认与重传(附谢希仁习题解析)
  • 别再死记硬背公式了!图解OpenCV C++灰度变换:线性、对数、伽马变换的本质与视觉原理
  • 如何训练使用——焊接焊缝缺陷检测数据集,5类,1400张。
  • LanzouAPI:一键获取蓝奏云直链的智能解析工具
  • 2026秋季游戏排期全解:41款产品的“逃难”数据
  • Rust 异步 TCP 与自定义协议解析:从字节流到结构化消息
  • ESP32/STM32可用的双模无线CNC雕刻固件,含蓝牙+WiFi完整驱动与G代码执行能力
  • 如何拯救损坏的二维码?免费网页工具QRazyBox终极恢复指南
  • 告别人工值守!AI客服智能体搭配知识库实现服务提效
  • 阿拉伯语网页一键启用模板:含RTL布局、预设字体与响应式样式
  • 【小白也能轻松用】保姆级零基础教学,OpenClaw 零代码一键部署全解析(含最新安装包)
  • 卡梅德生物技术快报|兔单克隆抗体应用实战:禽源病原 IFA 检测全流程拆解
  • 2026年宜宾装修公司真实口碑观察:哪些本地企业值得关注? - 优质品牌商家
  • 影刀RPA完全指南_团队共用RPA平台搭建流程管理监控与任务调度