顶点片段着色器:复杂、灵活度尕高、用到CG
语义绑定
- 顶点的模型坐标 float4 POSITION
- 顶点的屏幕坐标 float4 SV_POSTION
- 顶点法线向量坐标 float3 NORMAL
- 第⼀个UV坐标 float4 TEXCOORD0
- 第⼆个…第四个UV坐标 float4 TEXCOORD1…3
- 顶点切线向量坐标 float4 TENGENT
- 顶点颜色值 float4 COLO
示例代码
示例1
Shader "Zhongdudu/nine"
{
Properties
{
_MainCol("颜色",Color)=(1,0,0,1)
}
SubShader
{
Pass
{
CGPROGRAM //------CG开始------
//顶点着色器的编译指令
//每有一个顶点就执行一次
#pragma vertex vert
//片段着色器的编译指令
//每有一个像素就执行一次
#pragma fragment frag
//声明外部属性
fixed4 _MainCol;
//顶点函数
//参数输入:模型坐标;返回值输出:屏幕坐标
half4 vert(half4 localPos:POSITION):SV_POSITION //语义绑定,返回的是什么就绑什么
{
//将模型坐标转换为屏幕坐标
return UnityObjectToClipPos(localPos);
}
//片段函数
//返回值语义绑定:每个像素的颜色
fixed4 frag():COLOR
{
return _MainCol;
}
ENDCG //------CG结束------
}
}
}
示例2
Shader "Zhongdudu/ten"
{
Properties
{
_ColorOffset("颜色偏移量",Range(-0.5,1.5))=0.2
_RedOffset("红色偏移量",Range(-0.5,2))=0
_GreenOffset("绿色偏移量",Range(-0.5,2))=0
_BlueOffset("蓝色偏移量",Range(-0.5,2))=0
}
SubShader
{
Pass
{
CGPROGRAM //------CG开始------
//顶点着色器的编译指令
//每有一个顶点就执行一次
#pragma vertex vert
//片段着色器的编译指令
//每有一个像素就执行一次
#pragma fragment frag
//声明外部属性
fixed _ColorOffset;
fixed _RedOffset;
fixed _GreenOffset;
fixed _BlueOffset;
//顶点函数输出结构体
struct v2f
{
//屏幕坐标
half4 clipPos:SV_POSITION;
//理解为一个临时变量,用于存储本地坐标
fixed4 lPos:TEXCOORD0;
};
//顶点函数
//参数输入:模型坐标;返回值输出:v2f结构体
v2f vert(half4 localPos:POSITION)
{
//声明一个结构体对象
v2f o;
//将本地坐标临时存储到v2f中
o.lPos = localPos +
half4(_RedOffset,
_GreenOffset,_BlueOffset,0);
//将屏幕坐标输出到v2f
o.clipPos = UnityObjectToClipPos(localPos);
//最终返回这个结构体对象
return o;
}
//片段函数
//参数输入:v2f;返回值语义绑定:每个像素的颜色
fixed4 frag(v2f input):COLOR
{
//将v2f中的本地坐标当成一个颜色去返回
return input.lPos;
}
ENDCG //------CG结束------
}
}
}
示例3
Shader "Zhongdudu/zero"
{
Properties
{
_DiffuseColor("漫反射颜色",Color)=(1,0,0,1)
}
SubShader
{
Pass
{
Tags{ "LightMode"="ForwardBase" }
CGPROGRAM //------CG开始------
//顶点着色器的编译指令
//每有一个顶点就执行一次
#pragma vertex vert
//片段着色器的编译指令
//每有一个像素就执行一次
#pragma fragment frag
#include "UnityCG.cginc"
//顶点输入结构体
struct appdata
{
//顶点模型坐标
half4 vertexPos:POSITION;
//顶点法线向量
half3 vertexNormal:NORMAL;
};
//顶点输出结构体
struct v2f
{
//顶点屏幕坐标
half4 screenPos:SV_POSITION;
//顶点屏幕法线
half3 screenNormal:NORMAL;
};
//声明漫反射颜色属性
fixed4 _DiffuseColor;
//光照颜色【内部变量】
fixed4 _LightColor0;
//顶点函数
v2f vert(appdata data)
{
//顶点输出结构体对象
v2f o;
//将顶点模型坐标,转换为顶点屏幕坐标
o.screenPos = UnityObjectToClipPos(data.vertexPos);
//将顶点模型法线,转换为顶点屏幕法线
o.screenNormal = mul(half4(data.vertexNormal,1),unity_WorldToObject).xyz;
//返回结果
return o;
}
//片段函数
half4 frag(v2f vertexInput):COLOR
{
//求入射光线的单位向量
half3 lightDir = normalize(_WorldSpaceLightPos0);
//求法线向量的单位向量
half3 normalDir = normalize(vertexInput.screenNormal);
//通过漫反射公式计算所得每个像素的颜色【兰伯特】
//half3 diffuseColor = _DiffuseColor.rgb
//* _LightColor0.rgb
//* max(0,dot(lightDir,normalDir));
//通过漫反射公式计算所得每个像素的颜色【半兰伯特】
half3 diffuseColor = _DiffuseColor.rgb
* _LightColor0.rgb
* (0.5 * dot(lightDir,normalDir) + 0.5);
//漫反射颜色再加上环境光
return half4(diffuseColor,1) + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG //------CG结束------
}
}
}