基本数据类型与surface一致,就不在此文章赘述了
顶点语义绑定
float4 POSITION 顶点坐标位置
float3 NORMAL 顶点法线向量坐标
float4 TEXCOORD0 第一个UV坐标
float4 TEXCOORD1..N 第二个到第N个UV坐标
float4 TENGENT 顶点切线向量坐标
float4 COLOR 顶点颜色值
常用函数库
HLSLSupport.cginc 辅助为跨平台的着色器编译宏和定义
UnityShaderVariables.cginc 常⽤用全局变量量
UnityCG.cginc 常⽤用辅助函数
AutoLight.cginc 光、影函数
Lighting.cginc 光照模型相关
TerrainEngine.cginc 地形植被辅助
首先我们应该知道顶点片段着色器的基本框架
Shader "MyVFShader/VFShader_001"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
//预编译指令关键词 | 函数类型 | 函数名
#pragma vertex vert //vertex 是顶点着色器
#pragma fragment frag // fragment 是片段着色器
void vert(){}
void frag(){}
ENDCG
}
}
}
接下来先来用顶点片段着色器写一个纯色的Shader
Shader "MyVFShader/VFShader_002"
{
Properties
{
_MainColor("颜色",Color) = (1,1,1,1)
}
SubShader
{
Pass
{
CGPROGRAM
//预编译指令关键词 | 函数类型 | 函数名
#pragma vertex vert //vertex 是顶点着色器
#pragma fragment frag // fragment 是片段着色器
//输入一个顶点坐标 名称vertexPos 语义绑定POSITION
//输出一个像素坐标 语义绑定SV_POSITION
float4 vert(float4 vertexPos:POSITION):SV_POSITION
{
//老版本写法(Model View Project矩阵变幻,得到每个像素的坐标位置)
return UnityObjectToClipPos(vertexPos);
//新版本写法UnityObjectToClipPos(顶点坐标)
return UnityObjectToClipPos(vertexPos);
}
float4 _MainColor;
//无输入 输出内插值颜色
float4 frag():COLOR
{
return _MainColor;
}
ENDCG
}
}
}
/*
我们来说一下步骤和思路 做一个总结
首先看顶点函数
1.参数 --> 每个顶点的坐标位置 语义绑定是POSITION 类型是float4
2.返回值 --> 每个顶点的像素位置 语义绑定是SV_POSITION 类型是float4
3.顶点函数的作用:就是将三维空间坐标投影到二维窗口
然后看片段函数
1.参数 --> 片段函数没有参数
2.返回值 --> 片段的颜色值 语义绑定COLOR 类型是float4
3.片段函数的作用:就是给片段颜色赋值,也就是设置片段颜色
*/
如果感觉纯色的太局限了 我们来写一下彩色的看看效果
Shader "MyVFShader/VFShader_003"
{
Properties
{
//_ColorOffset("颜色偏移量",Range(0,1)) = 0.5
_ROffset("红色偏移量",Range(0,1)) = 0
_GOffset("绿色偏移量",Range(0,1)) = 0
_BOffset("蓝色偏移量",Range(0,1)) = 0
}
SubShader
{
Pass
{
CGPROGRAM
//预编译指令关键词 | 函数类型 | 函数名
#pragma vertex vert //vertex 是顶点着色器
#pragma fragment frag // fragment 是片段着色器
//顶点输出的结构体
struct V2F
{
//像素坐标
float4 position:POSITION;
//0级纹理坐标(可以理解为像素的颜色)
float4 color:TEXCOORD0;
};
float _ROffset;
float _GOffset;
float _BOffset;
//顶点函数
//输入一个顶点坐标 名称vertexPos 语义绑定POSITION
V2F vert(float4 vertexPos:POSITION)
{
//声明结构体
V2F v2f;
//通过顶点坐标求像素坐标
v2f.position = UnityObjectToClipPos(vertexPos);
//顶点坐标当做颜色值设置成像素颜色
//通过红,绿,蓝三个颜色的偏移量来修改颜色的变化
v2f.color = vertexPos + float4(_ROffset,_GOffset,_BOffset,0);
//返回
return v2f;
}
//片段函数
float4 frag(V2F v2f):COLOR
{
return v2f.color;
}
ENDCG
}
}
}
/*
我们来说一下步骤和思路 做一个总结
顶点着⾊色器器输出结构体
1.float4 postion:SV_POSITION 空间位置
2.float4 color:TEXCOORD0 0级纹理理坐标
首先看顶点函数
1.参数 --> 每个顶点的坐标位置 语义绑定是POSITION 类型是float4
2.返回值 --> 输出结构体
3.顶点函数的作用:将三维空间坐标投影到⼆维口,颜⾊值设置为顶点坐标+偏移量(营造彩虹效果)
然后看片段函数
1.参数 --> 顶点着⾊器输出结构体
2.返回值 --> 片段的颜色值 语义绑定COLOR 类型是float4
3.片段函数的作用:直接将顶点输出的颜色设置到片段显示
*/
由浅至深的 接下来 我们看一下顶点片段着色器的漫反射应该怎样实现
Shader "MyVFShader/VFShader_004"
{
Properties
{
_Color("颜色",Color) = (1,0,0,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex ver
#pragma fragment frag
//引用库
#include "UnityCG.cginc"
//声明外部颜色变量
float4 _Color;
//声明内部光照颜色变量
float4 _LightColor0;
//顶点函数输入结构体
struct appData
{
//顶点坐标
float4 vertexPos:POSITION;
//顶点法线
float3 normal:NORMAL;
};
struct V2F
{
//像素坐标
float4 position:SV_POSITION;
//像素法线
float3 normal:NORMAL;
};
//顶点函数
V2F ver(appData data)
{
//定义输出结构体
V2F v2f;
//坐标系转换
v2f.position = UnityObjectToClipPos(data.vertexPos);
//从顶点法线 到 像素法线
v2f.normal = mul(float4(data.normal,0),unity_WorldToObject).xyz;
//返回
return v2f;
}
//片段函数
float4 frag(V2F v2f):COLOR
{
//求法线的单位向量
float3 v2fnormal = normalize(v2f.normal);
//求入射光的单位向量 _WorldSpaceLightPos0内部函数
float3 lnormal = normalize(_WorldSpaceLightPos0.xyz);
//逆向光公式:Diffuse=LightColor * MainColor * max(0,dot(N,L))
//正向光公式:Diffuse=LightColor * MainColor * -min(0,dot(N,L))
float3 diffuse = _LightColor0 * _Color * -min(0,dot(v2fnormal,lnormal));
//添加环境光
float4 newDiffuse = float4(diffuse,0) + UNITY_LIGHTMODEL_AMBIENT;
//返回颜色值
return newDiffuse;
}
ENDCG
}
}
FallBack "Diffuse"
}
/*
我们来说一下步骤和思路 做一个总结
第一步
1.引入库 #include “UnityCG.cginc”
顶点着色器输入结构体
1.顶点位置 语义绑定POSITION 类型float4
2.法线 语义绑定NORMAL 类型float3
顶点着⾊器输出结构体
1.像素位置 语义绑定SV_POSITION 类型float4
2.法线 语义绑定NORMAL 类型float3
全局变量声明
1.光照颜色 内部值 _LightColor0 类型float4
2.漫反射颜色 属性值 自己定义
首先看顶点函数
1.参数 --> 输入结构体
2.返回值 --> 输出结构体
3.步骤:
1.矩阵变幻
2.计算法线
1).输入法线扩充 : float4(input.normal, 0.0)
2).内部值 : unity_WorldToObject
3).法线计算 : mul(float4(input.normal, 0.0), unity_WorldToObject).xyz
然后看片段函数
1.参数 --> 顶点着⾊器输出结构体
2.返回值 --> 片段的颜色值 语义绑定COLOR 类型是float4
3.步骤:
1.获取输入法线方向(float3) normalize(input.normal)
2.获取入射光法线方向(float3)normalize(_WorldSpaceLightPos0.xyz)
3.计算漫反射值
1).逆向光公式:Diffuse=LightColor * MainColor * max(0,dot(N,L))
2).正向光公式:Diffuse=LightColor * MainColor * -min(0,dot(N,L))
i).LightColor 光照颜⾊色
ii).MainColor 漫反射颜⾊色
iii).N 输⼊入法线
iiii).L 光照法线
4.合并环境光
1).漫反射扩充 float4(diffuse, 1.0)
2).添加环境光 + UNITY_LIGHTMODEL_AMBIENT
5.返回结果 片段颜色
*/
Shader就先介绍这么多了,感谢大家的支持, 如果有人想要深入的研究,可以给我评论留言,我们一起讨论研究!!!!
本文介绍了Unity中Shader的基础使用,包括顶点语义绑定如POSITION、NORMAL、TEXCOORD等,以及常用的函数库如HLSLSupport.cginc、UnityShaderVariables.cginc等。通过示例展示了如何编写实现纯色和彩色效果的顶点片段着色器,逐步讲解了漫反射的实现。适合Shader初学者入门。


被折叠的 条评论
为什么被折叠?



