1. 程式人生 > 其它 >【UnityShader】單張紋理

【UnityShader】單張紋理

紋理最初的目的就是使用一張照片來控制模型的外觀。

使用紋理對映可以將圖片附著再模型表面。一般用一個二位座標(u,v)來表示紋理對映座標,也稱UV座標。

我們通常使用一張紋理來代替物體漫反射顏色。

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/Chapter7-SingleTexture"
{
    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
" fixed4 _Color; sampler2D _MainTex; fixed4 _Specular; float _Gloss; float4 _MainTex_ST;//紋理型別屬性 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 = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; 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+diffuse+specular,1.0); } ENDCG } } FallBack "Diffuse" }

在屬性裡聲明瞭_MainTex的紋理屬性,_Color來做 整體物體的色調控制

float4 _MainTex_ST;//紋理型別屬性

Unity中,使用紋理名_ST的方式來宣告某個紋理的屬性,對頂點紋理座標進行偏移和縮放。Unity也提供了一個內建巨集TRANSFORM_TEX來幫我們計算。

o.uv = v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;

計算過法線和光照方向後,進行紋理取樣。實質是利用tex2D函式取樣。第一個引數是要被取樣的紋理,第二個引數是紋理座標。

最後將取樣結果和顏色屬性_Color的乘積來作為材質的反射率。

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));

最後疊加漫反射,環境光和高光返回即可。