时间:2025-08-19 10:47
人气:
作者:admin
【从UnityURP开始探索游戏渲染】专栏-直达
#pragma fragment frag)。语义、纹理用途、SV_POSITION:裁剪空间顶点位置(必需),由顶点着色器输出TEXCOORD0-7:通用插值寄存器,存储UV坐标/自定义数据(如法线、视向量)COLOR0-1:顶点颜色通道,常用于渐变效果或数据传递NORMAL:世界空间法线向量(需手动计算后传递)SV_Target:写入渲染目标(默认颜色缓冲)SV_Depth:自定义深度值输出(需显式启用)| 语义 | 常用存储数据 | 典型应用场景 |
|---|---|---|
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生成) |
hlsl
// C#脚本中通过Material类设置纹理
material.SetTexture("_MainTex", Resources.Load<Texture2D>("Albedo"));
Material.SetTexture方法动态绑定纹理Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl),其中WS后缀表示世界空间坐标,RWS为相机相对坐标。移动端需注意通过SAMPLER宏声明采样器以兼容GLES2.0平台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实现的基础)
.jpg/size/w=2000?exp=1755055058&sig=fHXVYh-EvtNeMntSASBCkCS63OV5y1SfLqXMlL8RSbc&id=23924489-bbde-8081-8858-e139f81dcc5a&table=block&userId=f97b3955-c81a-4615-8bdb-f8deb4f3401c)
使用HLSL标准导数函数ddx/ddy
通过颜色梯度检测边缘
可调节阈值控制边缘灵敏度
兼容URP渲染管线
EdgeDetection.shader
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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,????)