编译指令
编译指令 | 功能:告知编辑器顶点和片段着色函数的名称 | |
顶点着色器的编译指令 每有一个顶点执行一次 | #pragma vertex vert | |
片元着色器的编译指令 每有一个像素就执行一次 | #progma fragment frga |
顶点语义绑定
顶点的模型坐标 | float4 POSITION |
顶点的屏幕坐标 | float4 SV_POSITION |
顶点的法线向量坐标 | float3 NORMAL |
第一个UV坐标 | float4 TEXCOORD0 |
第二个...第四个UV坐标 | float4 TEXCOORD1...3 |
顶点切线向量坐标 | float4 TENGENT |
顶点颜色值 | float4 COLOR |
常用函数库
辅助为跨平台的着色器编译宏和定义 | HLSLSupport.cginc |
常用全局变量 | UnityShaderVariables.cginc |
常用辅助函数 | UnityCG.cginc |
光、影函数 | AutoLight.cginc |
光照模型相关 | Lighting.cginc |
地形植被辅助 | TerrainEngine.cginc |
注意:函数库的源码地址Unity地址\Data\CGIncludes | |
|
UnityCG常用函数(UnityCG函数解释)
将顶点模型坐标转换为顶点屏幕坐标 | UnityObjectToClipPos |
实例(SubShader中必须要有Pass通道)
纯色Shader
顶点函数 | 参数 | 每个顶点的坐标位置 语义绑定:POSITION(坐标位置) float4 |
返回值 | 每个顶点的像素位置 语义绑定:SV_POSITION(像素位置) float4 | |
作用:将三维空间坐标投影到二维窗口 | ||
片段函数 | 参数 | 无 |
返回值 | 片段颜色值 float4 | |
作用:设置像素颜色 | ||
![]() |
彩色Shader
顶点着色器输出结构体 | 空间位置:float4 position:SV_POSITION 0级纹理坐标:float4 color:TEXCOORD0 | |
顶点函数 | 参数 | 每个顶点的坐标位置 语义绑定:POSITION(坐标位置) float4 |
返回值 | 输出结构体 | |
作用:将顶点当作色彩参数赋值 | ||
片段函数 | 参数 | 顶点着色器输出结构体 |
返回值 | 片段颜色 | |
作用:直接将顶点输出的颜色设置到像素中显示 | ||
![]() |
漫反射
进入库 | #include "UnityCG.cginc" | ||||||||
顶点输入结构体 | 顶点位置 | (float4)语义绑定:POSITION | |||||||
法线 | (float3)语义绑定:NORMAL | ||||||||
顶点输出结构体 | 像素位置 | (float4)语义绑定:SV_POSIITON | |||||||
法线 | (float3)语义绑定:NORMAL | ||||||||
全局变量声明 | 光照颜色(內部值) | (float4)_LightColor0 | |||||||
漫反射颜色(属性) | |||||||||
顶点函数 | 输入结构体——输入 | ||||||||
输出结构体——输出 | |||||||||
步骤 | 矩阵变换 | ||||||||
计算法线 输入法线扩充 float4(input.normal,0.0) 內部值 unity_WorldToObject 法线计算(固定公式) mul(float4(input.normal,0.0),unity_WorldToObject).xyz | |||||||||
片段函数 | 顶点输出结构体 | 输入 | |||||||
语义绑定(COLOR) | 输出 | ||||||||
步骤 | 获取输入法线方向(float3) normalize(input.normal) | ||||||||
获取入射光线法线方向(float3) normalize(_WorldSpaceLightPos0.xyz) 备注:_WorldSpaceLightPos0(入射光方向) | |||||||||
计算漫反射值(float3)
| |||||||||
合并环境光(float4)
| |||||||||
注意:需要在Pass通道中设置Tags为正向渲染 "LightMode" = "ForwardBase"(光照模式设置成正向渲染) |
// 顶点着色器的编译指令
// 每有一个顶点就执行一次
#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;
};
// 声明漫反射颜色属性
half4 _DiffuseCol;
// 光照颜色【内部变量】
half4 _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 = _DiffuseCol.rgb * _LightColor0.rgb * max(0,dot(lightDir,normalDir));
// 通过漫反射公式计算所得每个像素的颜色【半兰伯特】
half3 diffuseColor = _DiffuseCol.rgb * _LightColor0.rgb * (0.5 * (dot(lightDir,normalDir) + 0.5));
// 添加漫反射颜色再加上环境光
return half4(diffuseColor,1) + UNITY_LIGHTMODEL_AMBIENT;
}