Shader "Custom/testShader" {
properties
{
_Color("mycolor", Color)=(1,1,1,1)
_MainTex("shit",2D)="white"{}
_Specular("my Specular", Color) = (1,1,1,1)
_Gloss("my gloss", Range(8.0, 256)) = 20
}
subshader
{
pass
{
tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc" //才能使用_LightColor0
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST; //声明纹理的属性,ST是缩放和平移的缩写。
// _MainTex_ST.xy存储的是缩放值,_MainTex_ST.zw存储的是偏移值
fixed4 _Specular;
float _Gloss;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0; //将模型的第一组纹理坐标存储到该变量中
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float2 uv : TEXCOORD2;
};
v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(_Object2World, v.vertex).xyz;
o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
//o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal); //世界空间下的法线向量
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); //世界空间下的光照方向
fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb; //将采样结果和颜色属性相乘,作为材质的反射率
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //反射率与环境光照相乘,计算环境光
fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(worldNormal,worldLightDir)); //计算漫反射
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.WorldPos)); //返回世界空间中从该点到摄像机的观察方向
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)),_Gloss); //高光反射
return fixed4(ambient + diffuse + specular, 1.0);
}
ENDCG
}
}
FallBack "Specular"
}
【说明】
1. o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; //使用此纹理属性来对纹理坐标进行变换,得到最终的纹理坐标
2. tex2D()函数:对纹理进行采样。第一个参数是需要被采样的纹理,第二个float2类型的纹理坐标,返回计算得到的纹素值。
3. UnityCG.cginc 常用帮助函数:
WorldSpaceViewDir():输入一个模型空间的顶点位置,返回世界空间中从该点到摄像机的观察方向。
UnityWorldSpaceViewDir():输入一个世界空间中从该点到摄像机的观察方向。
ObjSpaceViewDir():输入一个模型空间中的顶点位置,返回模型空间中从该点到摄像机的观察方向。
WorldSpaceLightDir():仅用于前向渲染中。输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。
UnityWorldSpaceLightDir():同上,输入一个世界空间中的顶点位置,返回世界空间中从该点到光源的光照方向。
ObjSpaceLightDir():同上,输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。三者皆未归一化。
UnityObjectToWorldNormal():把法线方向从模型空间转换到世界空间中。
UnityObjectToWorldDir():把方向矢量从模型空间变换到世界空间中。
UnityWorldToObjectDir():把方向矢量从世界空间变换到模型空间中。
4. 纹理属性1:Texture Type
把纹理类型设置为Texture后,勾选“Alpha from Grayscale”,则每个通道的值将会由每个像素的灰度值生成。
若把纹理类型设置为Advanced,则会有更多的Format可供选择,最好尽量使用压缩格式。
纹理属性2:Warp Mode(决定了当纹理坐标超过[0,1]范围后将会如何被平铺)
1)Repeat:留小数。如果纹理坐标超过1,则他的整数部分会被舍弃,直接使用小数部分进行采样,这样的结果是纹理将会不断 重复。
2)Clamp:留整数。如果纹理坐标大于1,则截取1,若小于0则截取0。
纹理属性3:Filter Mode (决定了当纹理由于变换而产生拉伸时将会哪种滤波模式)
1)Point--Bilinear--Trilinear,按顺序得到的图片滤波效果依次提升,但性能也依次增大。
2)Point使用了最近邻滤波,适合像素风效果;Bilinear最常用,使用线性滤波,对于每个目标像素,它会找到4个邻近像素,因 此看起来像是被模糊化了;Trilinear和Bilinear几乎一样,只是它还会在多级渐远纹理之间进行混合,如果一张纹理没有使用 多级渐远纹理,则二者结果相同。