码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-01-29 15:46:11      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:应该   之间   结构体   app   cond   c51   类型   struct   color   

运行环境:
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,不渐变
技术分享图片
绿到红没有任何过度,有明确的分界线
技术分享图片

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

标签:应该   之间   结构体   app   cond   c51   类型   struct   color   

原文地址:http://blog.51cto.com/shuxiayeshou/2066394

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!