什么是ShaderLab?
" Shaderlab is a friend you can afford." - 尼古拉斯・弗朗西斯( Nicholas Francis)。
Unity Shader是Uniy为开发者提供的高层级的渲染抽象层,Shaderlab是Uniy提供的编写 Unity Shader的一种说明性语言。
左图是未使用unity shader,右图为unity shader!
在Unity中,Shader可以分为三种类型:
- 固定功能着色器(Fixed Function Shader)
对于一些较旧的设备(其GPU仅支持Directx7.0、 OPENGL1.5或 OPENGL ES1.1),它们不支持可编程管线着色器,因此,这时候我们就需要使用固定函数着色器( Fixed Function Shader)来完成渲染。这些着色器住往只可以完成一些非常简单的效果,已经逐渐被抛弃. - 表面着色器(Surface Shader)
表面着色器是Uniy自己创造的一种着色器代码类型, 是 Unity对顶点片元着色器的更高一层的抽象。它存在的价值在于, Unity为我们处理了很多光照细节, 简化了很多。Unity建议使用表面着色器来编写和光照有关的Shader。 - 顶点着色器&片段着色器 (Vertex Shader & Fragment Shader)
和OpenGL,Direct3D中的顶点着色器和片段着色器区别不大。顶点片段着色器比表面着色器使用更灵活、更强大,当然也更复杂。
顶点着色器:产生纹理坐标,颜色,点大小,雾坐标,然后把它们传递给裁剪阶段。
片段着色器:进行纹理查找,决定什么时候执行纹理查找,是否进行纹理查找,及把什么作为纹理坐标。
Unity Shader结构:
Shader "name"
{
//----------属性-----------
Properties
{
_MainTex("基本纹理",2D)="White"{} //2D纹理
_FloatName("Float Name", Float) = 0.5 //浮点数
_RangeName("Range Name", Range(0.1, 1)) = 0.1 //浮点数 (在指定范围内)
_ColorName("Color Name", Color) =(1, 1, 1, 1) // 颜色
_VectorName("Vector Name", Vector) =(1, 1, 1, 1) //定义一个四元素的容器(相当于Vector4)属性
_RectName("Rect name", Rect) = "white"{} //定义长方形(非2次方)纹理属性
_CubemapName("Cubemap Name", CUBE) = "" {} //定义立方贴图纹理属性
}
//----------子着色器(可以多个)----------
SubShader
{
//Pass通道(可以多个):一个Pass就是一次绘制。
Pass
{
//标签,可选的
[Tags] // Tags { "RenderType" = "Opaque" }
//状态设置,可选的
[RenderSetup]
//CG代码块(每个Pass中都可以包含自定义的Cg代码,从CGPROGRAM开始到ENDCG结束。)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//cpu传递到gpu的数据信息
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
//顶点着色器传递到片段着色器的数据
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
//顶点着色器
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
//纹理
sampler2D _MainTex;
//片段着色器
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);//获取纹理颜色值
return col;
}
ENDCG
}
}
//-----------备胎---------
//当上面的所有SubShader在显卡上都不能运行时,就会启用最低价的Shader,如下:漫反射shader
Fallback" Diffuse "
}
渲染状态设置:
Shaderlab提供了一系列渲染状态的设置指令,这些指令可以设置显卡的各种状态,例如是否开启混合/深度测试等。
例如:ZWrite Off
标签类型:
Sub Shader的标签(Tags)是一个键值对( Key/Value Pair),它的键和值都是字符串类型。这些键值对是 Sub Shader和渲染引擎之间的沟通桥梁。
例如:Tags { "RenderType" = "Opaque" }