找回密码
 立即注册
首页 业界区 科技 【渲染流水线】[光栅阶段]-[片元着色]以UnityURP为例 ...

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

聚怪闩 2025-8-19 09:06:55

  • 在Unity URP渲染管线中,光栅化阶段的片元着色器(Fragment Shader)是决定像素最终颜色的核心环节。
【从UnityURP开始探索游戏渲染】专栏-直达
核心功能‌:


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


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

输入结构体(v2f)语义


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


  • SV_Target:写入渲染目标(默认颜色缓冲)
  • SV_Depth:自定义深度值输出(需显式启用)
TEXCOORD0-7和COLOR0-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通道,超限需通过数据压缩或纹理烘焙解决
内容映射表

核心纹理变量

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

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

纹理变量名来源类/脚本用途说明_CameraColorTextureURP RendererFeature相机颜色缓冲(后处理输入)_CameraDepthTextureURP DepthTexture模式场景深度图(需在URP Asset中启用)_ScreenSpaceOcclusionSSAO效果屏幕空间环境遮蔽图(通过SSAO Renderer Feature生成)‌脚本动态引用示例‌
  1. hlsl
  2. // C#脚本中通过Material类设置纹理
  3. material.SetTexture("_MainTex", Resources.Load<Texture2D>("Albedo"));
复制代码

  • 该代码通过Material.SetTexture方法动态绑定纹理
  • 纹理变量命名遵循URP核心库规范(Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl),其中WS后缀表示世界空间坐标,RWS为相机相对坐标。移动端需注意通过SAMPLER宏声明采样器以兼容GLES2.0平台
纹理数组高级应用
  1. Texture2DArray _TextureArray;  // 声明纹理数组
  2. float _LayerIndex;             // 动态切换纹理层  
  3. fixed4 frag(v2f i) : SV_Target {
  4.      return tex2DArray(_TextureArray, float3(i.uv, _LayerIndex));
  5. }
复制代码
该技术适用于地形系统(不同区块材质切换)或角色换装系统
片元着色器中的导数信息

每次片元着色器处理片元时都独立处理单个片元,因此片元在处理时无法得到临近片元信息。
实际GPU在运行时并不是只运行一个片元着色器,而是将其2x2的一组片元块,同时运行4个片元着色器。 通过ddx和ddy(URP中可通过ddx/ddy函数获取屏幕空间导数)两个偏导函数求得临近片元的差值。(偏导函数时纹理mipmaps实现的基础)
1.jpg

作用‌:


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


  • 使用HLSL标准导数函数ddx/ddy
  • 通过颜色梯度检测边缘
  • 可调节阈值控制边缘灵敏度
  • 兼容URP渲染管线
  • EdgeDetection.shader
    1. Shader "Custom/EdgeDetection" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.         _EdgeColor ("Edge Color", Color) = (1,0,0,1)
    5.         _Threshold ("Threshold", Range(0,1)) = 0.1
    6.     }
    7.     SubShader {
    8.         Pass {
    9.             HLSLPROGRAM
    10.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    11.             
    12.             TEXTURE2D(_MainTex);
    13.             SAMPLER(sampler_MainTex);
    14.             float4 _EdgeColor;
    15.             float _Threshold;
    16.             struct v2f {
    17.                 float4 pos : SV_POSITION;
    18.                 float2 uv : TEXCOORD0;
    19.             };
    20.             v2f vert(Attributes v) {
    21.                 v2f o;
    22.                 o.pos = TransformObjectToHClip(v.positionOS);
    23.                 o.uv = v.uv;
    24.                 return o;
    25.             }
    26.             half4 frag(v2f i) : SV_Target {
    27.                 half3 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv).rgb;
    28.                
    29.                 // 计算屏幕空间导数
    30.                 half3 dx = ddx(col);
    31.                 half3 dy = ddy(col);
    32.                 float edge = sqrt(dot(dx,dx) + dot(dy,dy));
    33.                
    34.                 // 边缘检测
    35.                 edge = step(_Threshold, edge);
    36.                 return lerp(float4(col,1), _EdgeColor, edge);
    37.             }
    38.             ENDHLSL
    39.         }
    40.     }
    41. }
    复制代码
延迟渲染中,片元着色器会利用G缓冲中的深度/法线信息进行更精确的光照计算,而前向渲染则直接在每个Pass中处理光照(内置管线每个pass处理灯光,URP中将所有灯光汇聚在一个Pass中处理)。URP通过优化后的着色器变体减少重复计算,提升多光源场景性能。
【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册