Unity —— Shader基础
UnityShader基础
最简单的Shader
设置模型的颜色为白色
输入结构体

按照给定的名字进行使用,Unity会自动为结构体填充内容,texcoord使用 0 ,是大家公认的第一套UV;
对结构体名字的解释
a:application,即从渲染流中通过Unity自动添加的
2:即 to 的谐音,
v:vertex,代表顶点着色器
最后意思是从程序中输入到顶点着色器中的结构体
输出结构体
属性控制
1 | _Color("Color",Color)=(1,1,1,1) //在属性块中的属性 |
库自带输入输出结构体
在UnityCG.cginc库文件中,有官方已经实现的输入结构和部分输出结构,使用的时候使用C++的头文件导入形式
1 | #include "UnityCg.cginc" |
1 | struct appdata full{ |
着色器语意
顶点着色器输入结构中的常见语义
语义 | 描述 |
---|---|
POSITION | 模型空间中的顶点位置,通常是float4类型 |
NORMAL | 顶点法线,通常是float3类型 |
TANGENT | 顶点切线,通常是float4类型 |
TEXCOORDn,如TEXCOORD0,TEXCOORD1 | 该顶点的纹理坐标,TEXCOORD0表示第一组坐标纹理,依次类推,通常是float2,float4类型 |
COLOR | 顶点颜色,通常是fixed4或float4类型 |
简单介绍各个版本Shader中对于TEXCOORD的支持数量
Shader Model版本 | TEXCOORDn中N的支持个数 |
---|---|
Shader Model2 | 8 |
Shader Model3 | 8 |
Shader Model4 | 16 |
Shader Model5 | 16 |
顶点着色器输出结构体中常用语义
语义 | 描述 |
---|---|
SV_POSITION | 裁剪空间中的顶点坐标,结构体中必须包含一个用该语义修饰的变量。等同于DX9中的POSITION。 |
COLOR0 | 通常用于输出第一组顶点颜色,不是必须 |
COLOR1 | 通常用于输出第二组顶点颜色,不是必须 |
TEXCOORD0-TEXCOORD7 | 通常用于输出纹理坐标,不是必须 |
片元着色器输出时的常见语义
语义 | 描述 |
---|---|
SV_Target | 输出值将会储存到渲染目标(render target)中。等同于DX9中COLOR语义。 |
调试
颜色测试输出
1 | v2f o; |
FrameDebug
在Unity的windows工具类中,在性能分析那一栏,选中可以使用Frame Debug对Shader的每个阶段进行排查测试
第三方工具:Inter Gpa , Snapdragon Profiler等
平台差异
抗锯齿下的手动翻转
开启Anti Aliasing,并且同时处理多张渲染图像是,DX平台需要翻转
UNITY_UV_STARTS_AT_TOP判断当前平台是否是DX平台,使用_MainTex_TexelSize.y<0来判断是否开启了抗锯齿。
知识补充:开启Anti Aliasing 抗锯齿可以通过项目设置的质量进入

不同图形接口的数据初始化
1 | float4 v= float4(0);//OpenGL |
表面着色器中初始化
1 | UNITY_INITIALIZE_OUTPUT(Input,o); |
Cg数据类型
1,基本数据类型:Cg支持7种基本的数据类型,分别是:
float, 32 位浮点数据,一个符号位。浮点数据类型被所有的 profile 支持
half,16 为浮点数据
int,32 位整形数据,有些 profile 会将 int 类型作为 float 类型使用
fixed,12 位定点数,被所有的 fragment profiles 所支持
bool,布尔数据,通常用于 if 和条件操作符( ?: ) ,布尔数据类型被所有的profiles 支持
simpler*, 纹理对象的句柄( the handle to a texture object ) ,分为 6 类:
sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT 。DirectX profiles 不支持 samplerRECT 类型, 除此之外这些类型被所有的 pixelprofiles 和 NV40 vertex program profile 所支持( CgUsersManual 30 页) 。由此可见,在不远的未来,顶点程序也将广泛支持纹理操作
string,字符类型,该类型不被当前存在的 profile 所支持,实际上也没有必要在 Cg 程序中用到字符类型,但是你可以通过 Cg runtime API 声明该类型变量,并赋值;因此,该类型变量可以保存 Cg 文件的信息。
前6种类型为常用类型,string类型几乎不使用。此外,Cg还提供了内置的向量数据类型 (built-in vector data types) ,内置的向量数据类型基于基础数据类型。 例如: float4, 表示 float 类型的 4 元向量; bool4, 表示 bool类型 4 元向量。
不同类型的浮点数在pc上最终被改变为float进行计算,而移动端上的fix又是一个古老的东西,现在基本不使用,因此在编写的时候时候围绕 half 和 float 进行曹组就可以了
2.数组
数组数据类型在Cg中的作用:作为函数的形参,用于大量数据的传递,例如:顶点参数数组、光照参数数据等。
一维数组:
1 | float a[10];//声明了一个数组,包含 10 个 float 类型数据 |
多维数组:
1 | float b[2] [3] = {{0.0, 0.0, 0.0},{1.0, 1.0, 1.0}}; |
3,结构体
结构体的声明以关键字 struct 开始,然后紧跟结构体的名字,接下来是一个大括号,并以分号结尾(不要忘了分号) 。大括号中是结构体的定义,分为两大类:成员变量和成员函数。
Unity支持的Shader Target
指令 | 描述 |
---|---|
#pragma target 2.0 | 相当于D3D9上的Shader Model2.0,不支持顶点纹理采样,不支持显示的LOD纹理采样 |
#pragma target 3.0 | 相当于D3D9上的Shader Model3.0 支持顶点纹理采样 |
#pragma target 4.0 | 相当于 D3D10上的Shader Model4.0支持几何着色器 |
#pragma target 5.0 | 相当于D3D11上的Shader Model5.0 |
补充
尽量少用if else,分支中指令尽量少
GPU并行运行的特性,ifelse中的每个分支都会运行一次,但是最终有些没用上,浪费资源