开始着手写Unity Shader之前,有必要了解一下用什么语言来写,Unity支持自家的Surface Shaders,GLSL,Cg/HLSL这几种方式来写,经过比较决定使用Cg/HLSL来写,今天就来初步学习一下Cg/HLSL语言,为接下来的使用做准备。
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
v2f o;
v2f vert (appdata_t v)
{
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
o.color = v.color;
return o;
}
fixed4 frag (v2f IN) : COLOR
{
return tex2D(_MainTex, IN.texcoord) * IN.color;
}
ENDCG
CG程序被放到CGPROGRAM…ENDCG的声明块中,指明这里是写CG语言。CG语言非常像C语言的语法,有C,C++,Java等基础的非常好掌握。
告诉编译器需要用到的函数和一些编译项的设置
- #pragma vertex name–指定vertex顶点shader的函数,name是函数名
- #pragma fragment–指定fragment片段shader的函数
- #pragma geometry name–指定geometry几何shader的函数(DX10以上)
- #pragma hull name–指定hull外壳着色器 Shader(细分着色的部分,主要负责定义细分等级(LOD)和相关控制点在细分中的“形变”趋势,DX11)
- #pragma domain name–指定domain域着色器Shader(负责的最重要的功能就是通过贴图控制的方式,实现模型的形变,DX11)
- #pragma target name–指定编译目标版本以适应不同的GPU
- #pragma require feature-细粒度控制shader需要GPU的哪个特性
- #pragma only_renderers space separated names–只编译指定的渲染器,默认编译所有的渲染器
- #pragma exlude_renderers space separated names –不编译指定的渲染器
- #pragma multi_compile … -指定 multiple shader variants
- #pragma enable_d3d11_debug_symbols-为
- #pragma hardware_tier_variants renderer name–为每一个编译的shader生成 multiple shader hardware variants
-其中#pragma vertex 和 #pragma fragment必须有,其它视情况选择使用。
这个和C,C++一样,表示包含外部的脚本文件。这里指包含Unity预先定义好的公共UnityCG.cginc库。
通过语义绑定机制,指定数据存放的位置,即将输入\输出数据和寄存器做一个映射关系。
- POSITION:用于vertex shader 输入,输出,fragment shader的输入,代表位置信息
- NORMAL:用于vertex shader 输入,代表顶点法线
- BINORMAL:用于vertex shader输入,代表顶点次法线
- BLENDINDICES:用于vertex shader输入,代表四个影响顶点的骨骼的索引
- BLENDWEIGHT:用于vertex shader输入,代表四个骨骼影响顶点的加权百分比
- TANGENT:用于vertex shader输入,代表顶点切线空间
- PSIZE:用于vertex shader输入,输出,fragment shader的输入,代表点的大小Point size
- TEXCOORD0~TEXCOORD7:用于vertex shader输入,输出,fragment shader的输入,代表贴图
- FOG:vertex shader 输出,fragment shader 输入,代表雾
- COLOR0~COLOR1:vertex shader 输出,fragment shader 输入,代表颜色
- COLOR:fragment shader 输出,代表颜色
- SV_POSITION:SV_前缀的变量代表system value,DX10之后推荐使用SV_POSITION作为vertex shader的输出和fragment shader的输入,注意vertex shader的输入还是使用POSITION
函数的定义和声明,同C语法类似
以上就是CG的主要语法,比较好掌握,内置的函数,vertex shader,fragment shader的具体执行和调用方式,在真正写Shader后再慢慢学习,这篇主要是为之后的编写Shader做准备。