Unity中正确使用Lerp

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中正确使用Lerp相关的知识,希望对你有一定的参考价值。

参考技术A 本文转自 blueraja
Unity官方示例中关于Lerp()函数的使用并非匀速插值,原因是Lerp()的from参数是在不断更新的,若想实现匀速插值效果,应按照类似下述方法。

最后附上Lerp()的内部实现:

ShaderLab学习小结用插值函数lerp渐变颜色

运行环境:
Win10 x64
Unity 5.5.4
在场景中创建一个cube,使它的颜色产生简单的两种颜色过渡的渐变效果,如下图:
技术分享图片
先说一下CG语言中的lerp函数
lerp(a, b, w);

a与b为同类形,即都是float或者float2之类的,那lerp函数返回的结果也是与ab同类型的值。
w是比重,在0到1之间
当w为0时返回a,为1时返回b,在01之间时,以比重w将ab进行线性插值计算。

功能很简单,实现也很简单。
Shader代码:

Shader "Custom/TestRedYellow" {
    Properties{
        _MainColor("MainColor", color) = (0,1,0,1)           //第一种颜色:绿
        _SecondColor("SecondColor", color) = (1,0,0,1) //第二种颜色:红
        _Center("Center", range(-0.51,0.51)) = 0              //中心点y坐标值
        _R("R", range(0,1)) = 0.2                                         //产生渐变的范围值
    }
    SubShader {
        pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            fixed4 _MainColor;
            fixed4 _SecondColor;
            float _Center;
            float _R;
            struct v2f {
                float4 pos:POSITION;
                float y : TEXCOORD0;
            };
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.y = v.vertex.y;
                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                float y = IN.y;
                float s = y -( _Center - _R/2);
                float f = saturate(s / _R);
                fixed4 col = lerp(_MainColor, _SecondColor, f);
                return col;
            }
            ENDCG
        }
    }
}

对y值的判断和颜色的插值要写在片断程序中才能产生图上的渐变效果,写在顶点程序中是不行的,因为只有八个角八个顶点,非红即绿,不会有颜色渐变。
但是要在顶点程序中获取物体坐标系下的y坐标,所以结构体中定义了y,且在顶点程序中赋值:

o.y = v.vertex.y;

再在片断程序中获取:

float y =IN.y;

以_R为范围,其实是在中心点_Center两端从-R/2到R/2这个范围中
这个颜色渐变的范围的起点应该是:(_Center-R/2)。

float s = y -( _Center - _R/2);

(注意:Center-R/2为颜色渐变的范围的起点y坐标,或者说是范围的下端点坐标,范围长度是_R。
这个起点可以根据需要自己调整,也可以就是_Center,或者别的值。)

代码中插值函数的比重 f为:

float f = saturate(s / _R);

当s<0时,即y坐标在_Center以下,且距_Center大于_R/2的距离,f=0,则返回的颜色为_MainColor,即我们定义的绿。
当s>_R时,即y坐标在_Center以上,且距_Center大于_R/2的距离,f=1,则返回的颜色为_SecondColor,即我们定义的红。

这样,最终结果为,以cube的y坐标_Center为中心,以长度为_R的(_Center-_R/2, _Center+_R/2)为范围,对_MainColor和_SecondColor进行渐变处理。小于此范围的显示_MainColor,大于此范围的显示_SecondColor。

Unity的Inspector面板中的材质:
我们将中心点_Center设置为0,即cube中心,渐变范围_R设置为1
技术分享图片
这样就能实现cube从下至上整体的从绿到红的颜色渐变了(看起来效果比较明显)
技术分享图片
将_R调节至0,即渐变范围为0,不渐变
技术分享图片
绿到红没有任何过度,有明确的分界线
技术分享图片

以上是关于Unity中正确使用Lerp的主要内容,如果未能解决你的问题,请参考以下文章

Unity Viewbob 使用 lerp 随机回弹 1 帧

Unity - 使用 foreach 循环以及父对象和子对象进行 Lerp 旋转?

Unity3D中的线性插值Lerp()函数解析

Unity物体移动的几种方式与表现(Lerp,SmoothDamp,MoveTowards的区别)

unity的color.lerp怎么用

unity 怎么sprite一直在屏幕范围内移动