记录
Shader脚本的结构
Shader "URPStudy/URPSample01" //urpshader路径脚本名命名
{
Properties //通过材质面板传入的属性
{
//....
}
SubShader{ //子着色器
Pass{ //着色器下可以是多个pass,每个pass可以认为是一次渲染
//todo...
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError" //填写故障情况下最保守shader的pass路径
}
一个shader脚本有多个SubShader,不同的SubShader可以提供给不同的硬件平台
编写一个简单的着色器
Shader "Custom/URPSample01"
{
Properties //通过材质面板传入的属性
{
}
SubShader //子着色器(高配)
{
LOD 600
Pass
{
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#pragma vertex vert; //顶点
#pragma fragment frag; //片元
struct appdata
{
float3 pos : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.pos = TransformObjectToHClip(v.pos.xyz);
// o.pos = mul(UNITY_MATRIX_MVP,v.pos);
return o;
}
half4 frag(v2f i) : SV_Target
{
return half4(1,1,1,1);
}
ENDHLSL
}
}
SubShader //子着色器(低配)
{
LOD 200
Pass
{
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#pragma vertex vert; //顶点
#pragma fragment frag; //片元
struct appdata
{
float3 pos : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.pos = TransformObjectToHClip(v.pos.xyz);
// o.pos = mul(UNITY_MATRIX_MVP,v.pos);
return o;
}
half4 frag(v2f i) : SV_Target
{
return half4(1,0,0,1);
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError" //填写故障情况下最保守shader的pass路径
}
}
主要下这里,在URP管线下一定需要在HLSL程序脚本里面包含#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"这个hlsl库,使用mul(UNITY_MATRIX_MVP,v.pos)做定点变换也不会有效果需要使用URP的hlsl库的TransformObjectToHClip函数来进行定点变换,在 URP 中,矩阵系统被重构,不再直接提供 UNITY_MATRIX_MVP。
这里每个SubShader脚本内有个LOD指令,可以通过C#脚本代码Shader.globalMaximumLOD = 600来控制使用哪个SubShader。
Properties属性块
Properties //通过材质面板传入的属性
{
_MainColor("Main Color",Color) = (1,1,1,1)
_ColorIntensity("Color Intensity",Range(0,1)) = 1
_MainTex("MainTexture",2d) = "white"{}
}
往Properties里面添加材质面板可控制的属性,使用在HLSL程序块里面需要进代码里面嵌入一下代码才能在对应的着色器上面使用
Pass
{
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#pragma vertex vert; //顶点
#pragma fragment frag; //片元
float _ColorIntensity;
half4 _MainColor;
TEXTURE2D(_MainTex); //纹理
SAMPLER(sampler_MainTex); //纹理采样器
struct appdata
{
float3 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.pos = TransformObjectToHClip(v.pos.xyz);
o.uv = v.uv;
return o;
}
half4 frag(v2f i) : SV_Target
{
half4 mainTexColor = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);
return mainTexColor * _MainColor * _ColorIntensity;
}
ENDHLSL
}
Tag的定义和使用
Tags
{
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
添加Tags标签,里面的RenderPipeline = UniverisalPipeline的作用是当前的SubShader只能用于URP管线,Queue是控制渲染队列的,填写Geometry是不透明物体,Transparent是半透明,不透明和半透明的渲染顺序是不一样的,URP会用一个DrawOpaque的指令了从近到远渲染不透明物体,和一个DrawTransParent指令从远到近渲染半透明物体
多Pass下可以加的一些参数
Tags
{
"LightMode" = "UniversalForward"
//Shadow Caster
//DepthOnly => CameraDepthTexture
//DepthNormals => CameraDepthTexture + CameraNormalTexture
//Meta
//Universal2D
//SPRDefaultUnlit
}
Cull值的作用
Cull Back 渲染背部剔除
Cull Front 渲染剔除正面
Cull Off 不进行渲染剔除
ZTest深度测试
ZTest LEqual //小于等于通过
//less 小于通过
//Greater 大于通过
//Equal 等于
//NotEqual 不等于
//Alwaays 一定通过
Alpha混合
Blend这个指令可以获取混合目标值和源目标值
One 此输入的值是 one。该值用于使用源或目标的颜色的值。
Zero 此输入的值是 zero。该值用于删除源或目标值。
SrcColor GPU 将此输入的值乘以源颜色值。
SrcAlpha GPU 将此输入的值乘以源 Alpha 值。
DstColor GPU 将此输入的值乘以帧缓冲区的源颜色值。
DstAlpha GPU 将此输入的值乘以帧缓冲区的源 Alpha 值。
OneMinusSrcColor GPU 将此输入的值乘以(1 - 源颜色)。
OneMinusSrcAlpha GPU 将此输入的值乘以(1 - 源 Alpha)。
OneMinusDstColor GPU 将此输入的值乘以(1 - 目标颜色)。
OneMinusDstAlpha GPU 将此输入的值乘以(1 - 目标 Alpha)。
BlendOp可以控制混合目标值和源目标的计算方式
Add 将源和目标相加。
Sub 从源减去目标。
RevSub 从目标减去源。
Min 使用源和目标中的较小者。(参见注释 1)
Max 使用源和目标中的较大者。(参见注释 1)
LogicalClear 逻辑操作:Clear (0)(参见注释 2)
LogicalSet 逻辑操作:Set (1)(参见注释 2)
LogicalCopy 逻辑操作:Copy (s)(参见注释 2)
LogicalCopyInverted 逻辑操作:Copy inverted (!s) 2
LogicalNoop 逻辑操作:Noop (d)(参见注释 2)
LogicalInvert 逻辑操作:Invert (!d)(参见注释 2)
LogicalAnd 逻辑操作:And (s & d)(参见注释 2)
LogicalNand 逻辑操作:Nand !(s & d)(参见注释 2)
LogicalOr Logical operation: Or (s | d) (See note 2)
LogicalNor Logical operation: Nor !(s | d) (See note 2)
LogicalXor 逻辑操作:Xor (s ^ d)(参见注释 2)
LogicalEquiv 逻辑操作:Equivalence !(s ^ d)(参见注释 2)
LogicalAndReverse 逻辑操作:Reverse And (s & !d)(参见注释 2)
LogicalAndInverted 逻辑操作:Inverted And (!s & d)(参见注释 2)
LogicalOrReverse Logical operation: Reverse Or (s | !d) (See note 2)
LogicalOrInverted Logical operation: Inverted Or (!s | d) (See note 2)
Multiply 高级 OpenGL 混合操作: Multiply(参见注释 3)
Screen 高级 OpenGL 混合操作: Screen(参见注释 3)
Overlay 高级 OpenGL 混合操作: Overlay(参见注释 3)
Darken 高级 OpenGL 混合操作: Darken(参见注释 3)
Lighten 高级 OpenGL 混合操作: Lighten(参见注释 3)
ColorDodge 高级 OpenGL 混合操作: ColorDodge(参见注释 3)
ColorBurn 高级 OpenGL 混合操作: ColorBurn(参见注释 3)
HardLight 高级 OpenGL 混合操作: HardLight(参见注释 3)
SoftLight 高级 OpenGL 混合操作: SoftLight(参见注释 3)
Difference 高级 OpenGL 混合操作: Difference(参见注释 3)
Exclusion 高级 OpenGL 混合操作: Exclusion(参见注释 3)
HSLHue 高级 OpenGL 混合操作: HSLHue(参见注释 3)
HSLSaturation 高级 OpenGL 混合操作: HSLSaturation(参见注释 3)
HSLColor 高级 OpenGL 混合操作: HSLColor(参见注释 3)
HSLLuminosity 高级 OpenGL 混合操作: HSLLuminosity(参见注释 3)
多pass urp shader
//在URP管线下编写多pass shader的方法
//1.RenderObject 可视化,傻瓜,只对使用特定的LightMode的材质生效
//2.RenderFeature C#脚本,可控性好
HLSL规范,srp batch开启修改
脚本修改
Shader "Custom/URPSample01"
{
Properties //通过材质面板传入的属性
{
_MainColor("Main Color",Color) = (1,1,1,1)
_ColorIntensity("Color Intensity",Range(0,1)) = 1
_MainTex("MainTexture",2d) = "white"{}
}
SubShader //子着色器(高配)
{
LOD 600
Tags
{
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Geometry"
}
//多pass下需要共用的变量,使用HLSLINCLUDE/ENDHLSL
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//开启SRP Batch 兼容需要把这些使用到的变量发到CBUFFER里面
CBUFFER_START(UnityPerMetatrial)
float _ColorIntensity;
half4 _MainColor;
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
CBUFFER_END
ENDHLSL
//在URP管线下编写多pass shader的方法
//1.RenderObject 可视化,傻瓜,只对使用特定的LightMode的材质生效
//2.RenderFeature C#脚本,可控性好
Pass
{
Tags
{
"LightMode" = "UniversalForward"
//Shadow Caster
//DepthOnly => CameraDepthTexture
//DepthNormals => CameraDepthTexture + CameraNormalTexture
//Meta
//Universal2D
//SPRDefaultUnlit
}
Cull Back
ZTest LEqual
HLSLPROGRAM
#pragma vertex unlitPassVert; //顶点
#pragma fragment unlitPassFrag; //片元
struct Attribute //urp命名规范:定点传入顶点数据需要改成 Attribute
{
float3 posOS : POSITION; //urp命名规范:不同的坐标系需要给命名弄上不同的后缀名 模型坐标os / 视图坐标vs / 世界坐标ws / 裁剪坐标 CS
float2 uv : TEXCOORD0;
};
struct Varying //urp命名规范:定点传入片元数据需要改成 Varying
{
float4 posCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varying unlitPassVert(Attribute v)
{
Varying o;
o.posCS = TransformObjectToHClip(v.posOS.xyz);
o.uv = v.uv;
return o;
}
half4 unlitPassFrag(Varying i) : SV_Target
{
half4 mainTexColor = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);
return mainTexColor * _MainColor * _ColorIntensity;
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError" //填写故障情况下最保守shader的pass路劲
}
URP管线变量
bool -对或错
float -32位浮点数。通常用于世界空间位置,纹理坐标或者涉及复杂函数的标量计算
half -16位浮点。用于短矢量,方向,物体空间位置、颜色
double -64位浮点。不能用作输入/输出
real -函数可以支持half或float时,在URP/HDRP中使用。使用 #define PREFER_HALF 0指令来控制real是half还是float
int -32为整数
uint -32无符号整数
Fixed 11位定点数,范围-2到2,通常表LDR颜色。HLSL不支持
float4 包含4个浮点的浮点向量
Half3 半进度向量,3个分量
Int2 整形2维向量