编译指令
编译指令 | 功能:告知编辑器顶点和片段着色函数的名称 | 顶点着色器的编译指令 每有一个顶点执行一次 | #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 | |
将顶点模型坐标转换为顶点屏幕坐标 | UnityObjectToClipPos |
实例(SubShader中必须要有Pass通道)
? ? ? ? 纯色Shader
顶点函数 | 参数 | 每个顶点的坐标位置 语义绑定:POSITION(坐标位置) float4 | 返回值 | 每个顶点的像素位置 语义绑定:SV_POSITION(像素位置) float4 | 作用:将三维空间坐标投影到二维窗口 | 片段函数 | 参数 | 无 | 返回值 | 片段颜色值 语义绑定:COLOR(颜色RGBA) 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)
公式 | 正向渲染公式 Diffuse=LightColor*MainColor*Max(0,dot(N,L)) | 变量解释 | LightColor(光照颜色) | MainColor(漫反射颜色) | 入射光(N) | 光照法线(L) |
| 合并环境光(float4)
漫反射扩充 | float4 (diffuse,1.0) | 添加环境光 | +UNITY_LIGHTMODEL_AMBIENT | 返回结果 |
| 注意:需要在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;
}
|