Unity URP法线贴图实现教程

发布于:2025-07-05 ⋅ 阅读:(21) ⋅ 点赞:(0)

前言

在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(简化版)

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"
        ENDHLSL
        
        Pass {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            struct 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
        }
    }
}

关键注意事项:

  1. 切线空间要求
  • 模型必须包含切线(Tangent)数据
  • 检查导入设置:Model > Normals & Tangents 设为 Calculate

  1. 性能优化
  • 移动平台使用 Normal Quality 设置为 Low(16位精度)
  • 复杂场景启用 Batching 减少Draw Calls

  1. 常见问题排查
  • 法线反向:尝试调整 Normal Scale 为负值
  • 接缝问题:确保UV展开无重叠,检查模型拓扑
  • 光照无反应:确认场景中有URP灯光(Directional Light)

增强效果技巧:

  • 视差贴图:在法线基础上添加高度偏移

    float2 parallaxUV = IN.uv + (tangentNormal.xy * _HeightScale);
  • 光滑度控制:将法线信息与粗糙度贴图结合
  • 双面渲染:添加 Cull Off 指令支持双面法线

通过以上步骤,可在URP中高效实现法线贴图效果,显著提升模型表面细节表现力。

更多教学视

Unity3D​www.bycwedu.com/promotion_channels/2146264125


网站公告

今日签到

点亮在社区的每一天
去签到