Unity Shader 渐变纹理

 纹理其实可以用于存储任何表面属性。一种常见的用法就是使用渐变纹理来控制漫反射光照的结果。

Shader "MyShader/RampTexture"
{
    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 worldNormal: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.worldNormal);

            o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

            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;

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

        return fixed4(ambient + diffuse + specular, 1.0);
        }
            ENDCG
        }
        }
            Fallback "Specular"
}

halfLambert 的范围被映射到了 [0,1] 之间。之后,我们使用 halfLambert 来构建一个纹理坐标,并用这个纹理坐标对渐变纹理 _RampTex 进行采样。由于 _RampTex 实际就是一个一维纹理(它在纵轴方向上颜色不变),因此纹理坐标的u和v方向我们都使用了halfLambert。然后,把从渐变纹理采样得到的颜色和材质颜色_Color 相乘,得到最终的漫反射颜色。

效果,ramp0

我们使用一张从紫色调到浅黄色调的渐变纹理。

效果ramp1

使用的渐变纹理是从黑色逐渐向浅灰色靠拢,而且中间的分界线部分微微发红。

效果ramp2

渐变纹理中的色调通常是突变的,即没有平滑过渡,以此来模拟卡通中的阴影色块。

各个图

需要注意的是,我们需要把渐变纹理的 Wrap Mode 设为 Clamp 模式,以防止对纹理进行采样时由于浮点数精度而造成的问题。

理论上halfLambert 的范围被映射到了 [0,1] 之间,但是可能出现1.00001这样的值。如果使用 Repeat 模式就会舍弃整数保留小数,得到的值就是0.00001,对应了渐变图中的最左边的值,即黑色。此时就会出现高光区域反而有黑点的情况。

参考 我买的 unity shader 入门精要

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值