Unity ShaderLab 个人学习笔记
周二 21 十二月 2021最近在回顾Unity的着色器知识。
这里主要记录个人在ShaderLab中遇到的一些重点内容。
这篇会做持续记录,直到完成此遍回顾。
ShaderLab的基本结构
ShaderLab是基于Cg(HLSL)的,但不等同于Cg。它在此基础上又添加了一套东西,是高于Shader的东西。
某种程度可以把ShaderLab代码等同于Unity的材质。它包含了整套东西,概念上像是HLSL基础之上的D3D Effects。
Shader "ShaderName" {
Properties {
// 属性
}
SubShader {
Pass {
// 具体的Shader程序
}
Pass {
// 有时会用到多个Pass
}
}
SubShader {
// 因为硬件的差异,有的旧硬件不支持某些Shader
// 可能需要提供多个子Shader供Unity选择
// Unity会选择第一个能运行的子Shader
}
// 当所有子Shader都不能运行时
// 提供一个应急方案,双引号里是Shader名称
// 或者关掉这个功能
// 代码是:Fallback off
Fallback "Diffuse"
}
注意这里Fallback有个隐藏影响,在Unity预计算阴影时,会在SubShader里找相关Pass,找不到就会用Fallback提供的。
Properties 属性设置
如果把Shader看成一套功能,或者广义的函数,那Properties就是Shader被提交给GPU执行时携带的参数。
...
Properies {
// 形式:
// Name("DisplayName", PropertyType) = DefaultValue
// 例如:
_pos("Position", Vector) = (1, 1, 1, 1)
}
...
这里_pos
可以在后面的Shader代码里作为“变量名”使用。
PropertyType支持Int
、Float
、Range(min,max)
、Color
、Vector
、2D
、Cube
、3D
这些类型,其中后3种是纹理类型。
贴图类型可以像这样:_tex("Texture", 2D) = "white"{}
,指定默认纹理。"white"
是默认纹理名称。
代码种的属性会对应到Unity材质属性设置面板中。
SubShader的一般结构
...
SubShader {
// 不一定要有
Tags {
// 标签块
// 键值对形式
}
// 不一定要有
RenderSetup {
// 状态设置块
}
Pass {
// Pass的名字,不一定要给
Name "Pass1"
// Pass的Tags
// 注意和和SubRender的不一样
// 也可以有Pass自己的RenderSetup
// CGPROGAM/ENDCG 表示该块是Cg代码
// GLSLPROGAM/ENDGLSL 表示该块是glsl代码
// 但是不推荐使用glsl,因为Unity能够将Cg交叉编译给glsl,反之不能
CGPROGRAM
// 指定具体的功能函数入口
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v : POSITION) : SV_POSITION {
return mul(UNITY_MATRIX_MVP, v);
}
fixed4 frag() : SV_Target {
return fixed4(1.0, 0.0, 0.0, 1.0);
}
ENDCG
}
}
...
Tags和RenderSetup放到后面记录。
其实ShaderLab还支持固定渲染管线,但是毕竟现在几乎已经没有了非可编程管线的硬件,就不做记录了。
RenderSetup 渲染状态设置
常用的状态表:
状态名 | 设置项目 | 解释 |
---|---|---|
Cull | Back, Front, Off | 剔除模式:背面、正面、关闭 |
ZTest | Less, Greater, LEqual, GEqual, Equal, NotEqual, Always | 深度测试: <、>、<=、>=、==、!=、总是 |
ZWrit | On, Off | 深度写入开关 |
Blend | 原模式,目的模式 | 打开并设置混合模式 |