【Shader笔记7】基础纹理-遮罩纹理

遮罩纹理

  1. 遮罩允许我们保护某些区域,使它们免于修改
  2. 使用遮罩纹理来控制光照,可以得到更加细腻的效果
  3. 使用遮罩纹理可以控制纹理的混合,比如裸露土地、草地的纹理等
  4. 原理:通过采样得到遮罩纹理的纹素值,然后使用某个通道的值与某种表面属性进行相乘,这样当该通道的值为0时,可以保护表面不受该属性的影响.
  5. 在实际的游戏制作中,我们充分利用一张遮罩的RGBA四个通道,来存储不同的属性:比如把高光反射的强度存储在R通道,把边缘光照的强度存储在G通道,把高光反射的指数部分存储在B通道,最后把自发光强度存储在A通道

效果:
【Shader笔记7】基础纹理-遮罩纹理_第1张图片

Shader "Custom/MaskTexture"
{
    Properties
    {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_MainTex("Main Tex",2D)="white"{}
		_BumpMap("Normal Map",2D)="bump"{}//“bump”没有指定法线贴图时,用自己顶点自带的法线
		_BumpSacle("Bump Scale",Float)=1.0

		_SpecularMask("Specular Mask",2D)="white"{} //高光反射遮罩纹理
		_SpecularScale("Specular Scale",Float)=1.0 //控制遮罩影响度的系数
		_Specular ("Specular", Color) = (1, 1, 1, 1)
		_Gloss ("Gloss", Range(8.0, 256)) = 20
    }
    SubShader
    {
        Tags { "LightMode"="ForwardBase" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

			#include"Lighting.cginc"
            #include "UnityCG.cginc"

            struct a2v
            {
                float4 vertex : POSITION;
				float3 normal:NORMAL;
				float4 tangent:TANGENT;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
				float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
				float3 lightDir:TEXCOORD1;
				float3 viewDir:TEXCOORD2;
            };

			fixed4 _Color;
			fixed4 _Specular;
			float _SpecularScale;
			float _BumpSacle;
			float4 _Gloss;

            sampler2D _MainTex;
			sampler2D _BumpMap;
			sampler2D _SpecularMask;

			//定义一个共用的纹理属性变量修改主纹理的平铺系数和偏移系数,会同时影响_MainTex,_BumpMap,_SpecularMask 三个纹理的采样
			//可以节省需要存储的纹理坐标数目(很多套纹理可以使用同一种平铺和位移操作)
            float4 _MainTex_ST; 

            v2f vert (a2v v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv.xy=v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;

				TANGENT_SPACE_ROTATION; 
				o.lightDir=mul(rotation,ObjSpaceLightDir(v.vertex)).xyz;  //Obj的O要大写
				o.viewDir=mul(rotation,ObjSpaceViewDir(v.vertex)).xyz;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed3 tangentLightDir=normalize(i.lightDir);
				fixed3 tangentViewDir=normalize(i.viewDir);
				fixed3 halfDir=normalize(tangentViewDir + tangentLightDir);
				
				//对遮罩纹理进行采样,因为rgb分量(三个值)都是一样的(从白到黑),这里使用r分量来计算掩码值
				fixed specularMask = tex2D(_SpecularMask,i.uv).r * _SpecularScale;

				fixed3 tangentNormal =UnpackNormal(tex2D(_BumpMap,i.uv));
				tangentNormal.xy *= _BumpSacle;
				tangentNormal.z =sqrt(1.0 - saturate(dot(tangentNormal.xy,tangentNormal.xy)));

				fixed3 albedo=tex2D(_MainTex,i.uv).rgb * _Color.rgb;          
			    fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
				fixed3 diffuse=_LightColor0.rgb * albedo * max(0, dot(tangentLightDir ,tangentNormal));  
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(tangentNormal, halfDir)), _Gloss) * specularMask;
			
				return fixed4(ambient + diffuse + specular, 1.0);
            }
            ENDCG
        }
    }
	FallBack"Specular"
}

你可能感兴趣的:(Shader)