Unity学习笔记(6) UnityShader学习笔记_5:纹理的使用——渐变纹理与遮罩纹理

笔记都是照着“Unity Shader入门精要”摘抄的,为以后想要复习实现方便。

渐变纹理

这个比较简单,实际就是为了光照强弱表现更为直观化地控制。
本质还只是色彩纹理,
只需要将渐变纹理运用到漫反射光照控制上。

Shader "Custom/Ramp Texture"{
    Properties{
        _Color ("Color tint", Color) = (1, 1, 1, 1)
        _RampTex ("Ramp 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 _RampTex;
            float4 _RampTex_ST;
            fixed4 _Specular;
            float _Gloss;

            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 = mul(v.normal, (float3x3)unity_WorldToObject);
                o.worldPos = mul(v.vertex, unity_WorldToObject).xyz;
                o.uv = TRANSFORM_TEX(v.texcoord, _RampTex);//计算平铺和偏移
                return o;
            }

            fixed4 frag(v2f i) : SV_Target{
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos));

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed halfLambert = 0.5 * dot(worldNormal, worldLight) + 0.5;
                fixed3 diffuseColor = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;

                fixed3 diffuse = _LightColor0.rgb * diffuseColor;

                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                fixed3 halfDir = normalize(worldLight + viewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)),_Gloss);

                return fixed4(ambient + diffuse /*+ specular*/, 1.0);
            }

            ENDCG
        }
    }
}

记得将WrapMode改成Clamp,这样才能避免因为浮点精度导致采样错误。比如1.0001会被采样到0.0001而不是1
20220120201652
这里把高光反射关掉了,更能突出渐变。
20220120202314

遮罩纹理

一种非常有用的纹理。
可以用来做精细的控制。
比如希望某些地方高光弱一些,有些强一些,比如混合多种纹理时,不同的纹理在不同的地方贡献度不同。

实例中实现的是,让墙缝的高光反射系数为0,而砖面具有一定的高光反射。
使用上一节做好了凹凸纹理的着色器代码。

Shader "Custom/MaskTexture"
{
    Properties{
        _Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
        _Specular ("Specular", Color) = (1, 1, 1, 1) //材质的高光反射颜色
        _Gloss ("Gloss", Range(8.0, 256)) = 20       //材质的高光反射区域大小
        _MainTex ("Main Tex", 2D) = "White" {}      //纹理贴图,默认纯白
        _Color ("Color Tint", Color) = (1, 1, 1, 1) //色调
        _BumpMap("Normal Map", 2D) = "bump" {}// bump是Unity自带的法线纹理
        _BumpScale("BumpScale", Float) = 1.0// 控制凹凸程度,为0时无凹凸

        _SpecularMask ("Specular Mask", 2D) = "white" {}        //+ 高光遮罩纹理
        _SpecularMaskScale ("Specular Mask Scale", Float) = 1.0 //+ 遮罩程度
    }
    SubShader{
        Pass{
            Tags{"LightMode" = "ForwardBase"}//定义了正确的LightMode,才能得到Unity内置的光照变量
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc" //使用内置库文件
            fixed4 _Diffuse; 
            fixed4 _Specular;
            float _Gloss;
            sampler2D _MainTex;     
            float4 _MainTex_ST;    
            fixed4 _Color;          
            sampler2D _BumpMap;     // 法线纹理图
            float _BumpScale;       // 凹凸程度

            sampler2D _SpecularMask;//+
            float _SpecularMaskScale;//+


            struct a2v{
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT; // 得到顶点的切线信息
                float4 texcoord : TEXCOORD0;
            };
            struct v2f{
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;      // 法线纹理也有缩放和平移的能力,一起在这里储存
                float3 lightDir : TEXCOORD1; // 切线空间中的光线方向
                float3 viewDir : TEXCOORD2; // 切线空间中的视角方向
            };

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

                TANGENT_SPACE_ROTATION;// 从模型空间转化到切线空间的矩阵,存放到rotation

                o.lightDir = normalize(mul(rotation, ObjSpaceLightDir(v.vertex)).xyz);
                o.viewDir = normalize(mul(rotation, ObjSpaceViewDir(v.vertex)).xyz);
                
                return o;
            }

            fixed4 frag(v2f i) : SV_Target{
                fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; 
                ambient *= albedo;

                // 光照计算,漫反射放在切线空间中计算,考虑纹理中的法线方向,而不是顶点的法线方向。
                fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw);
                fixed3 tangentNormal;// 对上面的像素解包成法线向量
                tangentNormal = UnpackNormal(packedNormal);
                tangentNormal.xy *= _BumpScale;
                tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
                fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, i.lightDir));
                
                // 高光反射放在切线空间中计算,考虑纹理中的法线方向,而不是顶点的法线方向。
                // 这里需要用到遮罩纹理
                fixed3 viewDir = normalize(i.lightDir + i.viewDir);
                fixed specularMask = tex2D(_SpecularMask, i.uv).r * _SpecularMaskScale;//+
                fixed3 specular = specularMask * _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(tangentNormal, viewDir)), _Gloss);//*

                fixed3 color = ambient + diffuse + specular;
                return fixed4(color, 1.0);
            }
            ENDCG
        }

    }
}

在没有运用高光遮罩时,对所有地方的高光系数都是一样的,而且很高,像是过曝了。
20220120213721
使用高光遮罩,就能解决这样的问题。
20220120215719

注意到图片有水印就不传素材图了,反正在书的Github的Unity Shader库里有所有的素材都有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值