【Unity Shader入门精要学习】基础纹理(一)
2019-08-25 本文已影响0人
小王子称号发放NPC
单张纹理
Shader "Unlit/SingleTexture"
{
Properties
{
_Color("Color Tint",Color)=(1.0,1.0,1.0,1.0)
_MainTex("Main Tex",2D) = "white"{}
_Specular("Specular",Color)=(1.0,1.0,1.0,1.0)
_Gloss("Gloss",Range(1.0,100.0)) = 30.0
}
SubShader
{
Pass
{
Tags{"LightModel"="ForwardBase"}
CGPROGRAM
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Specular;
float _Gloss;
struct a2v
{
float4 pos:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
struct v2f
{
float4 clipPos:SV_POSITION;
float4 worldPos:TEXCOORD0;
float3 worldNormal:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(a2v a)
{
v2f o;
o.clipPos = UnityObjectToClipPos(a.pos);
o.worldPos = mul(unity_ObjectToWorld,a.pos);
//o.worldNormal = mul(a.normal,unity_WorldToObject);
o.worldNormal = UnityObjectToWorldNormal(a.normal);
o.uv = a.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
//o.uv = TRANSFORM_TEX(a.texcoord,_MainTex);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
float3 worldNormal = normalize(v.worldNormal);
float3 worldLightDir = normalize(UnityWorldSpaceLightDir(_WorldSpaceLightPos0.xyz));
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(v.worldPos));
float3 halfNormal = normalize(worldLightDir + worldViewDir);
fixed3 albedo = tex2D(_MainTex,v.uv).rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,halfNormal)),_Gloss);
//diffuse
fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal,worldLightDir));
return fixed4(ambient + specular + diffuse,1.0);
}
ENDCG
}
}
FallBack "Specular"
}
注意shader中纹理坐标的变换:
o.uv = a.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.uv = TRANSFORM_TEX(a.texcoord,_MainTex);
1、纹理属性
wrap mode
wrap mode它决定了当纹理坐标超过[0,1]范围后将会如何平铺。它有两种模式:
(1)Repeat,在这种模式下,如果纹理坐标超过了1,那么它的整数部分会被舍弃,而直接使用小数部分进行采样,这样的结果是纹理将会不断重复(因为一直采样的是0--1之间的部分)
(2)clamp,这种模式下如果纹理坐标大于1,那么就会截取到1,如果小于0则会截取0。所以超过的部分则相当于绘制的是边界部分。
Filter Mode
Filter Mode它决定了当纹理由于变换而产生拉伸时将会采用哪种滤波模式。
Point,Bilinear,Trilinear,它们得到的图片滤波效果依次提升,但需消耗的性能也依次增大。纹理滤波会影响放大缩小纹理时得到的图片质量,例如有时需要把一张64X64的纹理贴在512X512的平面上,就需要放大图片。
(1)Point,使用了最邻近滤波,在放大缩小时,它采样的像素数目通常只有一个,因此图像看起来有一种像素风。
(2)Bilinear,使用了线性滤波,对于每个像素,它会找到4个邻近像素,然后对它们进行线性插值混合后得到最终像素,因此图像看起来像被模糊了
repeat+bilinear
(3)Trilinear,它几乎和Bilinear的效果是一样的,只是Trilinear还会在多级渐远纹理之间进行混合,如果一张纹理没有使用多级渐远,那么Trilinear和Bilinear的结果是一样的
repeat+trilinear
多级渐远纹理(mipmapping)
纹理的缩小过程比放大更加复杂一些,此时原纹理中的多个像素会将对应一个目标像素,往往需要处理抗锯齿问题,而多级渐远纹理就是为了处理这个问题的。
多级渐远纹理技术将原纹理提前用滤波处理以得到更多更小的图像,每一级都是对上一级的降采样结果。这样在实时运行时, 可以快速的得到结果像素,如当摄像机远离时可以使用较小的纹理。多级渐远纹理会增大内存占用空间,用空间换时间。
纹理的尺寸
尽量使用2的幂次方尺寸的纹理。