很久没写shader笔记了,最近一直在啃,刚刚有点新进度
这次来编写一个拥有两层UV通道的shader,通常第一层UV通道贴漫反射贴图,而第二层UV通道贴灯光贴图。
这里我制作了两种UV方案进行对比:两种方案的区别:
第一种:UV可以被平移,缩放操作。第二种UV不可以被用户平移缩放操作。
方案1
Shader "LiShader/mytest 1 "
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
_AOmap ("lightmap",2D) = "white"{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
//CG语言开始
CGPROGRAM
//像C#和java语言会有主函数main,这样程序运行的时候,先找主函数main运行,领起整个程序一样。
//shader也有主函数,但是是两个,一个顶点着色主函数,一个片元着色主函数。命名上自由一些,我们可以随便起名字
//我设置DingDianShader 是我的 顶点着色主函数。
#pragma vertex DingDianShader
//PianYuanShader 是我的 片元着色主函数。
#pragma fragment PianYuanShader
//然后倒入一个我们必须要用到的类,固定用法
#include "UnityCG.cginc"
//初始化GPU前端数据,准备送给顶点着色处理器。获取语义类型如下:顶点位置,UV1通道,UV2通道,这些语义类型是专有名字死记硬背吧。
struct appdata
{
float4 fbxvertex : POSITION;
float2 fbxuv : TEXCOORD0;
float2 fbxuv2 : TEXCOORD1;
};
//将顶点着色处理器的数据发送给片元着色器,发送的数据有如下:顶点位置,UV1通道,UV2通道
struct v2f1
{
float4 Myvertex : SV_POSITION;
float2 MyUV : TEXCOORD0;
float2 MyUV2 : TEXCOORD1;
};
//从内存中获取主贴图
uniform sampler2D _MainTex;
//从内存中获取AO贴图
uniform sampler2D _AOmap;
//需要一个内存空间来装UV1和UV2,声明这两个是为了对UV进行位移缩放操作。
float4 _MainTex_ST;
float4 _AOmap_ST;
//下面是顶点着色。 运行之后会将此环节的产物发送给片元着色,送进去的原料参数是appdata,到这里被命名为v
v2f1 DingDianShader (appdata v)
{
//因为结构体中有成员变量,所以需要再次声明成员变量
v2f1 o;
//下面开始GPU的顶点着色程序,这里我们并没有复杂的顶点计算,仅仅是直接继承而已,不做加工。
//UnityObjectToClipPos,固定用法,将物体坐标转成视口裁剪坐标
o.Myvertex = UnityObjectToClipPos(v.fbxvertex);
//TRANSFORM_TEX 是专有名词,功能:将贴图谁使用哪层坐标在网格上面进行映射。
o.MyUV = TRANSFORM_TEX(v.fbxuv, _MainTex);
o.MyUV2 = TRANSFORM_TEX(v.fbxuv2, _AOmap);
//最后输出o,然后会被送给片元着色器。
return o;
}
//片元着色器是在最开始CG命令的时候定义的。
fixed4 PianYuanShader (v2f1 i) : SV_Target
{
fixed4 col = tex2D(_MainTex,i.MyUV) * tex2D(_AOmap,i.MyUV2) * 2.0;
return col;
}
ENDCG
}
}
}
方案2
Shader "LiShader/mytest 1 "
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
_AOmap ("lightmap",2D) = "white"{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
//CG语言开始
CGPROGRAM
#pragma vertex DingDianShader
#pragma fragment PianYuanShader
#include "UnityCG.cginc"
struct appdata
{
float4 fbxvertex : POSITION;
float2 fbxuv : TEXCOORD0;
float2 fbxuv2 : TEXCOORD1;
};
struct v2f1
{
float4 Myvertex : SV_POSITION;
float2 MyUV : TEXCOORD0;
float2 MyUV2 : TEXCOORD1;
};
uniform sampler2D _MainTex;
uniform sampler2D _AOmap;
//float4 _MainTex_ST;注释掉
//float4 _AOmap_ST;注释掉
v2f1 DingDianShader (appdata v)
{
v2f1 o;
o.Myvertex = UnityObjectToClipPos(v.fbxvertex);
//下面两句不同了
o.MyUV = v.fbxuv.xy;
o.MyUV2 = v.fbxuv2.xy;
return o;
}
fixed4 PianYuanShader (v2f1 i) : SV_Target
{
fixed4 col = tex2D(_MainTex,i.MyUV) * tex2D(_AOmap,i.MyUV2) * 2.0;
return col;
}
ENDCG
}
}
}
配上一些环境效果,气氛就会更好。