Unity URP法线贴图实现教程
前言
在Unity URP(Universal Render Pipeline)中实现法线贴图效果,可以通过以下步骤完成。法线贴图通过修改表面法线方向模拟凹凸细节,无需增加几何复杂度。
对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!
完整实现步骤:
1. 准备法线贴图
- 使用图像软件(如Photoshop或Substance)创建法线贴图,或从资源商店获取
- 导入设置:
- 纹理类型:
Default
- 纹理形状:
Texture2D
- 勾选
Bump Map
(自动切换为法线贴图模式) - 压缩格式:推荐
BC5
(DXT5nm)或BC7
- 纹理类型:
2. 创建URP材质
- 在Project窗口右键:
Create > Material
- 使用URP内置着色器:
- 选择Shader:
Universal Render Pipeline > Lit
- 或
Universal Render Pipeline > Simple Lit
(简化版)
- 选择Shader:
3. 配置材质参数
- 在Material Inspector中:
Surface Type
:根据需求选 Opaque/Transparent- 将法线贴图拖拽到
Normal Map
插槽 - 调整
Normal Scale
(通常0.5-1.5)控制凹凸强度 - 设置基础贴图(Albedo)和其他参数
4. 应用到模型
- 将材质拖拽到场景中的模型上
- 确保模型有UV坐标(可在导入设置中检查)
5. 自定义Shader(可选进阶)
如果需要特殊效果,可编写自定义Shader:
Shader "Custom/NormalMapShader" {Properties {_MainTex("Albedo", 2D) = "white" {}_NormalMap("Normal Map", 2D) = "bump" {}_NormalScale("Normal Scale", Range(0,2)) = 1}SubShader {Tags { "RenderPipeline"="UniversalPipeline" }HLSLINCLUDE#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"ENDHLSLPass {HLSLPROGRAM#pragma vertex vert#pragma fragment fragstruct Attributes {float4 positionOS : POSITION;float2 uv : TEXCOORD0;float3 normalOS : NORMAL;float4 tangentOS : TANGENT;};struct Varyings {float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float3 normalWS : TEXCOORD1;float4 tangentWS : TEXCOORD2;};sampler2D _MainTex;sampler2D _NormalMap;float _NormalScale;Varyings vert(Attributes IN) {Varyings OUT;// 顶点变换VertexPositionInputs posInput = GetVertexPositionInputs(IN.positionOS.xyz);OUT.positionCS = posInput.positionCS;OUT.uv = IN.uv;// 法线和切线计算VertexNormalInputs normInput = GetVertexNormalInputs(IN.normalOS, IN.tangentOS);OUT.normalWS = normInput.normalWS;OUT.tangentWS = float4(normInput.tangentWS, IN.tangentOS.w);return OUT;}half4 frag(Varyings IN) : SV_Target {// 采样法线贴图float4 normalSample = tex2D(_NormalMap, IN.uv);float3 tangentNormal = UnpackNormalScale(normalSample, _NormalScale);// 构建TBN矩阵float3 normalWS = IN.normalWS;float3 tangentWS = IN.tangentWS.xyz;float3 bitangentWS = cross(normalWS, tangentWS) * IN.tangentWS.w;float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS);// 转换到世界空间float3 finalNormal = mul(tangentNormal, TBN);// 光照计算(简单漫反射)Light mainLight = GetMainLight();float NdotL = saturate(dot(finalNormal, mainLight.direction));half3 albedo = tex2D(_MainTex, IN.uv).rgb;half3 diffuse = albedo * NdotL * mainLight.color;return half4(diffuse, 1);}ENDHLSL}}
}
关键注意事项:
- 切线空间要求:
- 模型必须包含切线(Tangent)数据
- 检查导入设置:
Model > Normals & Tangents
设为Calculate
- 性能优化:
- 移动平台使用
Normal Quality
设置为Low
(16位精度) - 复杂场景启用
Batching
减少Draw Calls
- 常见问题排查:
- 法线反向:尝试调整
Normal Scale
为负值 - 接缝问题:确保UV展开无重叠,检查模型拓扑
- 光照无反应:确认场景中有URP灯光(Directional Light)
增强效果技巧:
- 视差贴图:在法线基础上添加高度偏移
float2 parallaxUV = IN.uv + (tangentNormal.xy * _HeightScale); - 光滑度控制:将法线信息与粗糙度贴图结合
- 双面渲染:添加
Cull Off
指令支持双面法线
通过以上步骤,可在URP中高效实现法线贴图效果,显著提升模型表面细节表现力。
更多教学视
Unity3Dwww.bycwedu.com/promotion_channels/2146264125