shader从入门到精通(连载三)
大家好,我是北京菜鸟在线的unity3d 高级讲师,范老师,今天给大家继续分享我的笔记 shader
继续上一章:
上面是一个最简单的着色器。
注意有以下几部分组成:
(1):ShaderLab 语法
(2):CG 语法
(3):两个#pragma, 一个#include
(4):定义一个变量,_MainTex和上面的变量一样,类型也一样
(5):一个结构体
(6):顶点函数
(7):片段函数
(8):最后一个 FallBack
几个开概念: 顶点,法线,切线
法线:它是垂直于一个面的顶点
关于 #include"UnityCG.cginc"库文件
打开 库文件:如下图
(2)当一个广告牌上,有好几个广告,滚动,一次只显示一个,下面,我们书写一个 shader 来制作广告牌效果。 新创建一个 shader 然后把里面的东西都删除掉,如下:然后,开始添加代码
Shader "Custom/NewShader" {
Properties {
}
SubShader {
}
FallBack "Diffuse"
}
具体更改如下::
Shader "myShaderMyShaderMyShader/NewShader" { // 菜单的路径
Properties {
_MainTex("MainTex", 2D) = "white"{}
}
SubShader {
Tags{"RenderType" = "Opaque"} // Opaque : 是不透明的 Transparent: 是透明的 标签
LOD 200 // 细节等级,这是可以调的,如果后面小于这个200 的话,那么,这个shader将不在显示,一般我们都写200
pass{ // pass 通道
CGPROGRAM // CG 语法
#pragma vertex vert // 声名一个顶点函数 函数名 vert // 顶点函数是处|理物体的形状
#pragma fragment frag // 声名一个片段函数 函数名 frag 变量是自己写的,可以随便写 // 片段函数是处|理物体的颜色的
#include"UnityCG.cginc" // 添加库文件t,这个库文件,是你安装工程中的
// 需要说明的是:库文件里,这个appdata_base是游戏对象上的Mesh Filter传递过来的,mesh Filter包含了各信息,下面的v2f也是自己起的名字
struct v2f{ //我们来写一个结构1体,来接收上面写的库文件t的那几个数据信息(顶点,法线,贴图)
float4 ver : POSITION; // 物体的顶点数据 // 在库文件里,把这三条复制过来。需要注意的是,变量的名字,尽量不要一样所以,我们要更改一下。把三个变量的后半截都删除掉
//float3 nor : NORMAL; // 物体的法线数y据Y
float4 tex : TEXCOORD0; // 物体的贴图数y据Y
}; // 注意这里是必须要分号结束的
// 创建一个顶点函数
v2f vert(appdata_base v)
{
v2f o;
// 让物体显示在屏幕上面的一条很神秘的代码。
o.ver = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord; // 得到 appdata_base里面的贴图信息,这texcoord是结构体里面的变量
return o; // 返回到片段函数里面
}
// 顶点到片段
fixed4 frag(v2f IN) : COLOR // color是颜色属性,你可以看做像是 js 里,color 声名了一个变量。
{
return fixed4(1,0,0,1); // 返回了一个红色
}
ENDCG
}
}
FallBack "Diffuse" // 最后的回调
}
把我们写的 shader 添加到Cube上,我们可以看到,这个Cube 就变成了红色。如下图:
那么,我们不想它返回一个颜色,我们想把它返回一个贴图,要怎么办呢? 我们需要对我们的shander 做出如下红色的代码更改:
Shader "myShaderMyShaderMyShader/NewShader" { // 菜单的路径
Properties {
_MainTex("MainTex", 2D) = "white"{}
}
SubShader {
Tags{"RenderType" = "Opaque"} // Opaque : 是不透明的 Transparent: 是透明的 标签
LOD 200 // 细节等级,这是可以调的,如果后面小于这个200 的话,那么,这个shader将不在显示,一般我们都写200
// cull back // 背面删除,意思就是当我们把这个shader放在plan面板上的时候,正面可以看到,背面是看不到的。
// cull front // 正面删除
// cull off // 两面都不删除
pass{ // pass 通道
CGPROGRAM // CG 语法
#pragma vertex vert // 声名一个顶点函数 函数名 vert // 顶点函数是处|理物体的形状
#pragma fragment frag // 声名一个片段函数 函数名 frag 变量是自己写的,可以随便写 // 片段函数是处|理物体的颜色的
#include"UnityCG.cginc" // 添加库文件t,这个库文件,是你安装工程中的
sampler2D _MainTex;
// 需要说明的是:库文件里,这个appdata_base是游戏对象上的Mesh Filter传递过来的,mesh Filter包含了各信息,下面的v2f也是自己起的名字
struct v2f{ //我们来写一个结构1体,来接收上面写的库文件t的那几个数据信息(顶点,法线,贴图)
float4 ver : POSITION; // 物体的顶点数据 // 在库文件里,把这三条复制过来。需要注意的是,变量的名字,尽量不要一样所以,我们要更改一下。把三个变量的后半截都删除掉
//float3 nor : NORMAL; // 物体的法线数y据Y
float4 tex : TEXCOORD0; // 物体的贴图数y据Y
}; // 注意这里是必须要分号结束的
// 创建一个顶点函数
v2f vert(appdata_base v)
{
v2f o;
// 让物体显示在屏幕上面的一条很神秘的代码。
o.ver = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord; // 得到 appdata_base里面的贴图信息,这texcoord是结构体里面的变量
return o; // 返回到片段函数里面
}
fixed4 frag(v2f IN) : COLOR // color是颜色属性,你可以看做像是 js 里,color 声名了一个变量。
{
IN.tex.x /= 5; // 把这个贴图分成五份
// IN.tex.x += 0.20 ; // 相当于把这个贴图只显示了五分之一。
IN.tex.x += _Time.x; // 运行程序的时候,就可以看到纹理贴图在缓慢的移动了。
return tex2D(_MainTex, IN.tex); // 返回纹理贴图
}
ENDCG
}
}
FallBack "Diffuse" // 最后的回调
}
回去unity3d 我们发现,游戏对象的纹理已经发生了改变
运行程序,就可以看到广告牌在移动了,每次显示一个广告。
需要注意的是:顶点函数是改变物体的形状。 片段函数是改变物体的颜色。
下一章,我们将用shader制作一个红旗飘扬的效果
《待续》