永远相信美好的事情即将发生 😊!

Unity Shader 入门精要(冯乐乐著)学习笔记(6)——基础纹理

学习 Mavis 66℃ 0评论

渐变纹理——一维纹理

使用渐变纹理来控制漫反射光照,采用半兰伯特模型得到halflambert(代表了法线和光线的夹角,夹角越接近90°,则更靠近纹理的左边颜色)。

Shader "Custom/渐变纹理"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _RampTex ("RampTex", 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:TEXCOORD;
            };
            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;  
                //使用内置的TRANSFORM_TEX计算经过平铺和偏移后的纹理的uv值
                o.uv = TRANSFORM_TEX(v.texcoord,_RampTex); 
                return o;
            }
            fixed4 frag(v2f i) : SV_Target {
                fixed3 worldNormal=normalize(i.worldNormal);
                fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
                //计算环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                //计算漫反射部分
                fixed halflambert=0.5*dot(worldNormal,worldLightDir)+0.5;//半兰伯特模型
                fixed3 diffuseColor=tex2D(_RampTex,fixed2(halflambert,halflambert)).rgb*_Color.rgb;
				fixed3 diffuse = _LightColor0.rgb * diffuseColor;
                //采用Blinn模型计算高光反射部分
                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"
}

效果:

需要注意将渐变纹理的WrapMode设置成为Clamp,以防止对纹理采样时由于浮点数精度造成的问题:

黑点的出现:halflambert可能会得到1.00001这样的值,采用repeat会导致截断后选取到了左边的黑色点0.00001,而不是右边的白色,所以在高光的地方出现了黑点,采用clamp模式则不会有这样的问题。


Mavis , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Unity Shader 入门精要(冯乐乐著)学习笔记(6)——基础纹理
喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址