Unity Shader入门教程(四) :单张的纹理贴图

    xiaoxiao2022-07-03  119

    首先我们需要了解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" }

     

    最新回复(0)