【渲染流水线】[光栅阶段]-[片元着色]以UnityURP为例

  • 在Unity URP渲染管线中,光栅化阶段的片元着色器(Fragment Shader)是决定像素最终颜色的核心环节。

【从UnityURP开始探索游戏渲染】专栏-直达

核心功能‌:

  • 纹理采样:通过UV坐标从贴图获取颜色数据
  • 光照计算:结合材质属性和光源信息计算逐像素光照
  • 特效处理:实现透明度混合、边缘检测等后处理效果

可配置‌:

  • 重写片元函数(#pragma fragment frag)。语义、纹理用途、

语义体系

输入结构体(v2f)语义

  • SV_POSITION:裁剪空间顶点位置(必需),由顶点着色器输出
  • TEXCOORD0-7:通用插值寄存器,存储UV坐标/自定义数据(如法线、视向量)
  • COLOR0-1:顶点颜色通道,常用于渐变效果或数据传递
  • NORMAL:世界空间法线向量(需手动计算后传递)

输出语义

  • SV_Target:写入渲染目标(默认颜色缓冲)
  • SV_Depth:自定义深度值输出(需显式启用)

TEXCOORD0-7COLOR0-1语义的常用数据存储内容

语义 常用存储数据 典型应用场景
TEXCOORD0 主纹理UV坐标 采样漫反射贴图(_MainTex)
TEXCOORD1 次要纹理UV坐标 光照贴图、细节纹理叠加
TEXCOORD2 世界空间法线向量 法线贴图计算、光照模型处理
TEXCOORD3 世界空间切线向量 切线空间转换、法线映射
TEXCOORD4 世界空间视线方向 高光反射计算、视差效果
TEXCOORD5 世界空间顶点位置 动态雾效、距离衰减计算
TEXCOORD6-7 自定义数据或额外UV集 顶点动画参数、流动贴图、多纹理混合
COLOR0 顶点颜色主通道 顶点着色效果、渐变色处理(如植被/地形)
COLOR1 顶点颜色辅助通道 特殊效果遮罩、动态参数传递(如溶解阈值)

关键说明:

  • 数据复用性

    TEXCOORD语义本质上是通用插值寄存器,实际用途根据Shader需求动态分配4。例如简单着色器可能仅用TEXCOORD0,而复杂PBR材质会占用更多通道。

  • 优化建议

    URP推荐将关联数据打包到同一寄存器(如法线/切线共用TEXCOORD2-3),减少插值计算开销。

  • 通道限制

    移动端平台最多支持8个TEXCOORD和2个COLOR通道,超限需通过数据压缩或纹理烘焙解决

内容映射表

核心纹理变量

纹理变量名 来源类/脚本 用途说明
_MainTex Material属性面板 基础颜色/Albedo贴图(通过[MainTexture]特性标记)
_BaseMap URP Shader内置变量 替代_MainTex的标准化命名(URP 7.0+版本推荐使用)
_NormalMap Standard Shader/自定义Shader 切线空间法线贴图(需配合BUMP关键字启用)
_MetallicGlossMap PBR材质系统 金属度(R)和光滑度(A)通道存储
_EmissionMap Material发光属性 自发光纹理(需启用_EMISSION关键字)

‌特殊功能纹理‌

纹理变量名 来源类/脚本 用途说明
_OcclusionMap 光照探针系统 环境光遮蔽贴图(通常存储在G通道)
_DetailAlbedoMap 细节层材质 表面微结构纹理(通过_DETAIL宏控制)
_ParallaxMap 高度图效果 视差偏移贴图(需启用_PARALLAXMAP
_SpecGlossMap 旧版高光工作流 高光颜色(RGB)和光滑度(A)替代金属度贴图

‌渲染管线专用纹理‌

纹理变量名 来源类/脚本 用途说明
_CameraColorTexture URP RendererFeature 相机颜色缓冲(后处理输入)
_CameraDepthTexture URP DepthTexture模式 场景深度图(需在URP Asset中启用)
_ScreenSpaceOcclusion SSAO效果 屏幕空间环境遮蔽图(通过SSAO Renderer Feature生成)

‌脚本动态引用示例‌

glsl 复制代码
hlsl
// C#脚本中通过Material类设置纹理
material.SetTexture("_MainTex", Resources.Load<Texture2D>("Albedo"));
  • 该代码通过Material.SetTexture方法动态绑定纹理
  • 纹理变量命名遵循URP核心库规范(Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl),其中WS后缀表示世界空间坐标,RWS为相机相对坐标。移动端需注意通过SAMPLER宏声明采样器以兼容GLES2.0平台

纹理数组高级应用

glsl 复制代码
Texture2DArray _TextureArray;  // 声明纹理数组 
float _LayerIndex;             // 动态切换纹理层  
fixed4 frag(v2f i) : SV_Target {
     return tex2DArray(_TextureArray, float3(i.uv, _LayerIndex));
}

该技术适用于地形系统(不同区块材质切换)或角色换装系统

片元着色器中的导数信息

每次片元着色器处理片元时都独立处理单个片元,因此片元在处理时无法得到临近片元信息。

实际GPU在运行时并不是只运行一个片元着色器,而是将其2x2的一组片元块,同时运行4个片元着色器。 通过ddx和ddy(URP中可通过ddx/ddy函数获取屏幕空间导数)两个偏导函数求得临近片元的差值。(偏导函数时纹理mipmaps实现的基础)

作用‌:

  • 边缘检测:通过颜色/深度突变识别物体轮廓
  • Mipmap层级选择:动态调整纹理采样精度
  • 屏幕空间特效:如SSAO、运动模糊等

URP中基于导数的边缘检测示例

  • 使用HLSL标准导数函数ddx/ddy

  • 通过颜色梯度检测边缘

  • 可调节阈值控制边缘灵敏度

  • 兼容URP渲染管线

  • EdgeDetection.shader

    glsl 复制代码
    Shader "Custom/EdgeDetection" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _EdgeColor ("Edge Color", Color) = (1,0,0,1)
            _Threshold ("Threshold", Range(0,1)) = 0.1
        }
        SubShader {
            Pass {
                HLSLPROGRAM
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
                
                TEXTURE2D(_MainTex);
                SAMPLER(sampler_MainTex);
                float4 _EdgeColor;
                float _Threshold;
    
                struct v2f {
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                v2f vert(Attributes v) {
                    v2f o;
                    o.pos = TransformObjectToHClip(v.positionOS);
                    o.uv = v.uv;
                    return o;
                }
    
                half4 frag(v2f i) : SV_Target {
                    half3 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv).rgb;
                    
                    // 计算屏幕空间导数
                    half3 dx = ddx(col);
                    half3 dy = ddy(col);
                    float edge = sqrt(dot(dx,dx) + dot(dy,dy));
                    
                    // 边缘检测
                    edge = step(_Threshold, edge);
                    return lerp(float4(col,1), _EdgeColor, edge);
                }
                ENDHLSL
            }
        }
    }

延迟渲染 中,片元着色器会利用G缓冲中的深度/法线信息进行更精确的光照计算,而前向渲染则直接在每个Pass中处理光照(内置管线每个pass处理灯光,URP中将所有灯光汇聚在一个Pass中处理)。URP通过优化后的着色器变体减少重复计算,提升多光源场景性能。


【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

相关推荐
NRatel1 小时前
Unity 游戏提升 Android TargetVersion 相关记录
android·游戏·unity·提升版本
★YUI★20 小时前
学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
java·学习·游戏·unity·c#
SmalBox21 小时前
【渲染流水线】[光栅阶段]-[光栅插值]以UnityURP为例
unity·渲染
谷宇.21 小时前
【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
游戏·unity·c#·游戏程序·unity3d·游戏开发·游戏编程
NRatel2 天前
亚马逊S3的使用简记(游戏资源发布更新)
游戏·unity·amazon s3
SmalBox2 天前
【渲染流水线】[几何阶段]-[屏幕映射]以UnityURP为例
unity·渲染
SmalBox3 天前
【渲染流水线】[几何阶段]-[归一化NDC]以UnityURP为例
unity·渲染
SmalBox4 天前
【渲染流水线】[几何阶段]-[图元装配]以UnityURP为例
unity·渲染
霜绛4 天前
Unity:GUI笔记(一)——文本、按钮、多选框和单选框、输入框和拖动条、图片绘制和框绘制
笔记·学习·unity·游戏引擎