Shader 基础使用(三) ----- vertex & fragment
2017-08-10 13:58
417 查看
基本数据类型与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
如果感觉纯色的太局限了 我们来写一下彩色的看看效果
由浅至深的 接下来 我们看一下顶点片段着色器的漫反射应该怎样实现
Shader就先介绍这么多了,感谢大家的支持, 如果有人想要深入的研究,可以给我评论留言,我们一起讨论研究!!!!
顶点语义绑定
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 中用 Vertex & Fragment Shader 实现 surface shader 中的 Diffuse 和 Decal
- Unity 使用 Vertex/Fragment Shader 完整实现 BumpMapping(NormalMapping)
- Android OpenGL ES零基础系列(三):OpenGL ES的渲染管道及VertexShader与FragmentShader
- UNITY3D shader学习心得<三> Vertex and Fragment Shader
- 【猫猫的Unity Shader之旅】之Vertex&Fragment Shader下的透明
- Vertex & Fragment Shader入门
- Vertex Texture Fetch(VTF) && Fragment Texture Fetch ( FTF )
- Java基础--->09.关于JDK使用旧方法编译出错、警告问题。
- Android基础——使用Fragment适应不同屏幕和分辨率
- Android基础之使用Fragment控制切换多个页面
- 使用的 ixgbe 基础驱动程序 , 适用于 10 千兆位英特尔®网络连接
- shader 2: vertex, fragment, surf的区别
- Fragment详解(一)--->核心基础以及Fragment与Activity传递数据完整示例
- 【LaTeX排版】LaTeX使用--入门基础<一>
- 【LaTeX排版】LaTeX使用--入门基础<二>
- Vertex Shader&Pixel Shader介绍
- D3D Vertex Shader & Pixel Shader
- 【Android基础 007】 <meta-data>使用方法