代码结构
//shader的名字会显示在unity的inspector中选择shader的菜单里面
Shader "Shader的路径和名称"{
//属性
[Properties]
//可能存在多个subshader。Unity会在所有的subshader列表中选中第一个硬件可以支持的subshader
SubShader{
//SubShader的标签
//[Tags]
//给该SubShader中所有pass公用的设置
//[Common State]
[Common Tags]
//可能存在多个pass,每个pass都会引起一次渲染
Pass{
//该Pass的标签
[Tags]
//渲染设置,如颜色混合
[Render Setup]
//纹理设置,只有在fixed function shader中才可用
[Texture Setup]
}
//可以有其他的Pass
[其他的Pass]
}
//可以有多个SubShader
[其他的SubShader]
//当所有的subshader失败时,使用Fallback指定的shader
[Fallback]
//当有自定义shader的设置UI时候用
[CustomEditor]
}
演示
名字
属性
对比固定管线和可编程shader的基础结构
固定管线shader和可编程shader的基础结构是一样的,只是Render Setup部分不同。
Render Setup语法
1. 固定管线shader
使用ShaderLab命令组成Render Setup代码。
2. 可编程shader
使用CG/HLSL语言编写Render Setup代码。
使用CG语言编写一段简单的雾效shader的Render Setup部分如下所示:
CGPROGRAM // 开始编写CG代码的标志
#pragma vertex vert // 定义一个定点着色器的入口函数,#pragma vertex 自定义函数名
#pragma fragment frag // 定义一个片段着色器的入口函数, #pragma fragment 自定义函数名
#include "UnityCG.cginc" // 文件包含在U3D的安装目录C:\Program Files\Unity\Editor\Data\CGIncludes,内置了很多数据和函数可供我们使用
// 数据结构名和变量名可以修改
// 定义顶点着色器的输入结构,通过预定义的语义从MeshRender中获取所需的顶点数据
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
// 定义定点着色器的输出结构,同时也是片段着色器的输入结构,是两个着色器传递数据的桥梁
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float fogData : TEXCOORD1;
}
// 编写自定义的顶点着色器
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
// CG中需要使用属性中定义的变量时,必须引用一下
sampler2D _MainTex;
// 编写自定义的片元着色器函数,输出最终的颜色值
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv)
return col;
}
ENDCG
Unity Shader常用语义
- POSITION: 获取模型顶点的信息
- NORMAL:获取法线信息
- TEXCOORD(n):高精度的从顶点着色器传递信息到片段着色器,比如自定义的值,可以是float、float2、float2、float4
COLOR:低精度的从顶点着色器传递信息到片段着色器 float4
TANGENT:获取切线信息SV_POSITION:经过mvp表示已经转化到屏幕坐标系(mvp)的坐标 顶点的三维左边已经编程了片段的二维坐标
SV_Target: 输出到哪个render target
常用的三种的顶点着色器获取fbx顶点信息的结构,可以自己增加或减少
struct appdata_base {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct appdata_tan {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct appdata_full {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
fixed4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};