首先我们需要了解Unity中纹理的属性。在Unity中导入一张图片并设置为纹理类型时,可以看到如下属性:
Alpha Source栏预选值分别代表:InputTextureAlpha表示该纹理需要带透明通道;FromGrayScale表示依据灰度产生alpha通道
Alpha Is Transparen :当alpha用于透明处理时,我们要勾上该选项,可以防止不透明边缘锯齿现象
Wrap Mode:它决定了纹理超过[0,1]时将选择什么样的方式平铺。
Repeat:超出部分将选择重复的方式平铺;Clamp:超出部分将截取边界值,形成一个条形结构;
Mirror:超出部分将以镜像的方式平铺;Mirror Once:字面理解是镜像一次,但结果跟Clamp效果一样(具体原因不明)。Per-axis:分别对U,V方向超出部分分开做平铺处理,U,V可以单独选择以上四项。其效果图分别对应如下:
Filter Mode:当纹理由于变换而产生拉伸时将采用哪种滤波方式。此模式支持3种:Point,Bilinear,Trilinear,他们得到的滤波效果依次提升,但需消耗的性能也依次增大。纹理滤波会影响放大和缩小纹理时的图片质量。下图为3种滤波模式下放大的结果
Advanced:多级渐远纹理,根据相机离物体的远近来显示不同滤波处理的不同大小的图像。例如相机离物体较远时则直接显示较小的纹理,缺点是会预先准备多张不同级别的纹理,典型的空间换取时间的做法。下面就是几种模式,具体几种模式对显示的结果有什么不同还在研究,一般勾选默认即可。
最下面表示不同平台下纹理对应的压缩格式,需要注意的是IOS平台下要使用ASTC的压缩格式,不然显示上会有锯齿。
最后,贴纹理的shader代码如下:
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Custom/SingleTex"
{
Properties
{
_Color ("Color Tint", Color) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {}
_Specular("Specular", Color) = (1,1,1,1)
_Gloss("Gloss",Range(8.0,256)) = 20
}
SubShader
{
Pass{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
fixed4 _Specular;
float _Gloss;
float4 _MainTex_ST;
struct a2v {
float4 vertex : POSITION;
float3 narmal : 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 = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.narmal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
//o.uv = v.texcoord.xy * _MainTex_ST.xy * _MainTex_ST.zw;//_MainTex_ST.xy代表纹理的缩放大小,_MainTex_ST.zw代表纹理的偏移量
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);//该宏定义为UnityCG.cginc库中定义,其计算方式为o.uv = v.texcoord.xy * _MainTex_ST.xy * _MainTex_ST.zw;
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 + specular + diffuse, 1.0);
}
ENDCG
}
}
FallBack "Specular"
}