顶点着色器和片段着色器作为性能不错,实现效果也很好的渲染方式,这里分几个小结着重说一说,然后所有关键字的使用以及特殊语义的含义都在代码里注释了,有不明白的可以讨论下:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
shader"likang/king05"
{
properties
{
_MainTex("baseTexture",2d) = "white"{}
}
//顶点着色器和片段着色器
subshader
{
pass
{
CGPROGRAM //必须大写,不然会报错
//cgprogram
#pragma vertex vert //vertex 不能大写 顶点着色器函数vert
#pragma fragment frag //fragment 不能大写 片段着色器函数frag
#include "unitycg.cginc" //引用库,包含很多辅助函数
sampler2D _MainTex; //纹理
//不声明_MainTex_ST 这个变量,下面的49行会报错,解释看52行
float4 _MainTex_ST; //纹理的缩放和偏移 就是Tiling/Offset 值(Tiling.x,Tiling.y,Offset.x,Offset.y)
struct v2f
{
//SV_POSITION 输出的数据结构包含了最终转换过的,将用于光栅化的顶点坐标
//POSITION 转换之前的模型顶点坐标(自身坐标轴)
//模型顶点坐标要经过一系列的矩阵变换,最终变成屏幕上的像素坐标
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0; //第一张贴图的uv坐标 TEXCOORD1 第二张贴图的uv坐标
};
//unity内置的常用数据结构
//appdata_base 其含义就是输入到顶点着色器的数据(包含position,normal,one texture coordinate)
//appdata_tan 输入到顶点着色器的数据(包含position,normal,tangent,one texture coordinate)
//appdata_full 输入到顶点着色器的数据(包含position,normal,tangent,vertex color,two texture coordinates)
//appdata_img 输入到顶点着色器的数据(包含position,one texture coordinate)
v2f vert(appdata_base v)
{
v2f o;
// o.pos = UnityObjectToClipPos(v.vertex);等同于o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
//前者性能上优于后者,unity推荐使用前者
//UNITY_MATRIX_MVP为unity内置的矩阵。该矩阵乘以顶点在模型坐标系下的坐标得到投影坐标
//类似的矩阵还有 UNITY_MATRIX_MV 模型坐标系(以模型某点为原点)-->观察者坐标系(以相机为原点)
//UNITY_MATRIX_VP 观察者坐标系-->投影坐标系
//UNITY_MATRIX_T_MV 转置模型-->观察者坐标系
//UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3 纹理变换矩阵 等等……
//mul(M,v) 矩阵与向量相乘 得到新的向量(模型坐标在投影坐标系下的新坐标)
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
//TRANSFORM_TEX 函数的含义就是将顶点的uv坐标和Tiling和Offset做运算
//因此你在shader属性中变化Tiling和Offset的值,纹理会发生改变
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
//上面的等式等同于o.uv = v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
//所以上面要声明_MainTex_ST变量,不然这里会报错
//如果采用默认的Tiling(1,1),Offset(0,0),那么在shader面板改变Tiling和Offset的值就没什么用了
// o.uv = v.texcoord.xy;
return o;
}
//将经过顶点着色器处理过的数据拿给片段着色器接着处理(给每个像素着色)
float4 frag(v2f i):COLOR
{
//tex2D函数 CG内置函数:用来采样2d纹理
float4 texCol = tex2D(_MainTex,i.uv);
return texCol;
}
ENDCG
//endcg
}
}
fallback"diffuse"
}