Unity:理解插值函数Lerp

我们先看一下它的函数签名和定义

从定义来看还是挺简单的,我们主要是理解它有什么作用。另外我们规定,weight是一个在区间[0,1]的实数,倒不是因为取更大的值之后,这个函数就无定义了,而是因为取更大的值,这个函数就失去了我们构造它的理由,另外,CG会限制weight的值在0-1的范围内,超过这个范围会被留在边界0或者边界1。

这里的y1被称为起点,而y2被称为终点,lerp函数就是取值y1到y2中间的一个值。取多少呢?就由weight来控制,当weight为0.5时,它正好落在起点和终点的中间。为了更加方便理解,我们可以把这个公式换成这种格式

简单来说,lerp函数就是在y1和y2之间过渡,唯一不同的地方就是,y1和y2可以是一个值,也可以是一个函数。比如,我们可以在正弦函数和线性函数之前做过渡,我们先看一下正弦函数

再看一下最简单的线性函数(恒等映射函数y=x)

在它俩之间做过渡,我们只需要写出lerp(sin(x),x,0.5)即可。当然,可以调整weight参数观察不同的结果。

weight为0.5时:

weight为0.8时:

weight为0.2时:

是不是非常的直观,所以这就扯到了Lerp函数的两种不同的作用。

  • 构造新的函数
  • 在两个值之间进行过度

我们可以通过Lerp函数来编写一个简单的Shader测试一下。

Shader "Sundry/LerpTest"{
        Properties{
            _BaseColor1("First Color",Color) = (1.0,1.0,1.0,1.0)
            _BaseColor2("Second Color",Color) = (1.0,1.0,1.0,1.0)
            _Weight("Lerp Weight",Range(0,1)) = 0.5
        }
    
        SubShader{
            pass{
                Tags{"LightMode"="ForwardBase"}
                CGPROGRAM
                #pragma vertex Vertex
                #pragma fragment Pixel
                #include "Lighting.cginc"
    
                struct vertexOutput{
    
                    float4 pos : SV_POSITION;
                    float3 worldNormal : TEXCOORD0;
                    float3 worldPos : TEXCOORD1;
                };
    
                fixed4 _BaseColor1;
                fixed4 _BaseColor2;
                fixed _Weight;
    
                vertexOutput Vertex(appdata_base v){
    
                    vertexOutput o;
                    o.pos = UnityObjectToClipPos(v.vertex);
                    o.worldNormal = UnityObjectToWorldNormal(v.normal);
                    o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
    
                    return o;
                }
    
                fixed4 Pixel(vertexOutput i):SV_TARGET{
    
                    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                    fixed3 worldNormal = normalize(i.worldNormal);
    
                    fixed3 albedo = lerp(_BaseColor1.xyz,_BaseColor2.xyz,_Weight);
                    //在颜色1和颜色2之间以weight过度
    
                    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
                    fixed3 diffuse = _LightColor0.xyz * albedo * saturate(dot(worldNormal,lightDir));
    
                    return fixed4(ambient + diffuse,1.0);
                }
    
                ENDCG
            }
        }
    }

它的最终效果如下,我们选择两种比较深的颜色来看一下。

参考资料:https://zhuanlan.zhihu.com/p/114898567

—— 完 ——
相关推荐
评论

立 为 非 似

中 谁 昨 此

宵 风 夜 星

。 露 , 辰

文章点击榜

细 无 轻 自

如 边 似 在

愁 丝 梦 飞

。 雨 , 花