关闭

【Unity Shader】如何修改LineRenderer与TrailRenderer 中的颜色

标签: unityShder
5471人阅读 评论(0) 收藏 举报
分类:

LineRender和TrailRender是两个好东西,很多Unity拖尾特效都会使用到它们。一些简单的介绍可以参见官方的API文档。
在这里探讨一下它们具体的渲染方式,而后给出一些Shader以便更好地控制它们。

最终我们可以实现类似这样的一个效果:
TrailRenderer

接下来,我们先了解LineRenderer。稍后的TailRenderer情况类似。

创建LineRender

LineRender是一个以顶点去控制渲染尺寸和位置的条带,顶点个数和具体坐标我们自己可以完全操控。
首先我们需要建立了一个GameObject,然后添加LineRenderer组件,然后填入一下参数:

LineRenderer参数
其实就是一个沿着X方向延展的一组顶点。然后新建一个材质,并把它拖入Materials。
由于当前你使用的是默认材质,所以目前只能获得以下的样子:

显示
就是一个矩形而已。

修改LineRenderer

首先,我们需要一张资源图片,大概是这样:

贴图
这个图片使用PSD制作一下,里面白色部分代表将来要在条带中显露出来的部分,黑色则是透明的部分。只有黑白两种颜色即可。注意要加入通道,即把这个黑白图片在PSD中新建一层透明通道,并且粘贴进去。最后让你的通道看起来是这样:

贴图通道

为什么只要黑白图,不需要颜色?解释一下:
我们用这个素材来构成条带的主要轮廓,而显示的色彩由其它参数控制,所以这里只需要黑白图就可以了。

开始写Shader

属性部分,就是一张贴图就可以了。

    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

Tags部分,我们需要设定处于半透明渲染队列,并且设定Alpha混合的模式,就是用最常见的Alpha混合的模式即可。

        Tags { "RenderType"="Transparent"  "IgnoreProjector"="True"  "Queue"="Transparent"}
        LOD 200
        Blend SrcAlpha OneMinusSrcAlpha

由于我们不需要光照,也不希望受到光照的影响,所以我们写一个直接返回原色的光照方程来避免默认的光照处理。同时,为了避免产生光照部分的Pass,添加noforwardadd参数,这样我们的渲染就只需要一个Pass。

CGPROGRAM
        #pragma surface surf NoLight vertex:vert alpha noforwardadd

        //光照方程,名字为Lighting接#pragma suface后的光照方程名称 
        //lightDir :顶点到光源的单位向量
        //viewDir  :顶点到摄像机的单位向量   
        //atten    :关照的衰减系数 
        float4 LightingNoLight(SurfaceOutput s, float3 lightDir,half3 viewDir, half atten) 
        { 
            float4 c ; 
            c.rgb =  s.Albedo;
            c.a = s.Alpha; 
            return c; 
        }

接下来是顶点着色器代码,我们只要将系统传递过来顶点颜色和UV坐标存储下来,以便于输入到表面着色器就可。

        sampler2D _MainTex;
        fixed4 _SelfCol;

        struct Input 
        {
            float2 uv_MainTex;
            float4 vertColor;
        };

        void vert(inout appdata_full v, out Input o)
        {
            o.vertColor = v.color;
            o.uv_MainTex = v.texcoord;
        }

最后就是最重要的部分,表面着色器代码:

        void surf (Input IN, inout SurfaceOutput o) 
        {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Alpha = c.a * IN.vertColor.a;
            o.Albedo = IN.vertColor.rgb;
        }


        ENDCG

其实也很简单:
这里我们只是提取了贴图上的 【像素颜色透明度】 X 【顶点颜色透明度】 作为最终透明度。这样做的目的就是为了提取贴图上的轮廓,同时透明度也会受到顶点颜色的影响。
使用【顶点颜色】作为最终颜色。
这样我们就可以通过LineRenderer的StartColor和EndColor来设定整个条带的颜色和透明度了。

使用之前的贴图和这个Shader,修改之前的材质。最终这个条带变成这样:

最终的条带

完整的Shader

Shader "AndrewBox/LineRenderer" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Transparent"  "IgnoreProjector"="True"  "Queue"="Transparent"}
        LOD 200
        Blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
        #pragma surface surf NoLight vertex:vert alpha noforwardadd

        //光照方程,名字为Lighting接#pragma suface后的光照方程名称 
        //lightDir :顶点到光源的单位向量
        //viewDir  :顶点到摄像机的单位向量   
        //atten    :关照的衰减系数 
        float4 LightingNoLight(SurfaceOutput s, float3 lightDir,half3 viewDir, half atten) 
        { 
            float4 c ; 
            c.rgb =  s.Albedo;
            c.a = s.Alpha; 
            return c; 
        }

        sampler2D _MainTex;
        fixed4 _SelfCol;

        struct Input 
        {
            float2 uv_MainTex;
            float4 vertColor;
        };

        void vert(inout appdata_full v, out Input o)
        {
            o.vertColor = v.color;
            o.uv_MainTex = v.texcoord;
        }

        void surf (Input IN, inout SurfaceOutput o) 
        {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Alpha = c.a * IN.vertColor.a;
            o.Albedo = IN.vertColor.rgb;
        }


        ENDCG
    } 
    FallBack "Diffuse"
}

TrailRenderer

TrailRenderer与LineRenderer很相似,又有些不同。不同之处在于:
首先,它的顶点构成是动态的,每帧你需要将产生TrailRenderer的GameObject移动到不同的位置,这样它会自动连接成一个轨迹。
其次,它由五个颜色值来进行控制整个条带的颜色变化,但是不像LineRenderer,在运行时你并不能修改这些颜色值,因为它的API中没有访问这五个颜色的方法,但是我们仍然可以通过Shader来进行改变。
记住最重要的一点就是,它和LineRenderer一样,都是把一组颜色值写入了顶点颜色,我们只要读取顶点颜色即可。
为了整体控制尾迹的颜色显示,我们增加一个主控制颜色,修改上面那个Shader。

    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _MainCol ("Self Color Value", Color) = (1,1,1,1)
    }

最后,在表面着色器中进行相应的修改

        void surf (Input IN, inout SurfaceOutput o) 
        {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            //c.a为贴图上的透明度,使用它构成条带的图形轮廓
            //_MainCol.a为主颜色的透明度,用于对整个条带透明度控制
            //IN.vertColor.a由顶点颜色获得,由Colors数组设置,用于控制条带不同位置的透明度度变化
            o.Alpha = c.a * _MainCol.a* IN.vertColor.a;
            //_MainCol.rgb为主颜色的颜色值,用于显示主颜色部分
            //IN.vertColor.rgb为顶点颜色的颜色值,由Colors数组设置,用于控制条带不同位置的颜色变化
            o.Albedo = _MainCol.rgb*IN.vertColor.rgb;
        }

这样,我们可以通过主控制颜色的变化来控制整体尾迹随着时间的颜色变化。而条带上颜色不同位置的变化,则由那五个颜色值进行控制。当我们只需要显示一个纯色条带时,将五个颜色都设置为白色和变化的透明度即可。
最后,TrailRender的显示效果如下:

TrailRender

当然你需要一个脚本来控制TrailRender所在的GameObject的旋转,代码相对简单。(BaseBehavior类的实现可以参见我的其它文章)

public class TrailRendererGen : BaseBehavior 
{
    [SerializeField][Tooltip("旋转角速度")]
    protected float m_angle=360;
    protected override void OnInitFirst()
    {
    }

    protected override void OnInitSecond()
    {
    }

    protected override void OnUpdate()
    {
        m_transform.Rotate(Vector3.forward, m_angle*Time.deltaTime);
    }
}

总结

最终,我们可以完整控制两种Renderer的渲染了,最重要的事情再说一遍,就是它们的Color设定都写入了顶点颜色,我们可以通过读取顶点颜色来完成自己想要的渲染效果。


本页资源下载:http://download.csdn.net/download/andrewfan/9764637


本文为博主原创文章,欢迎转载。请保留博主链接http://blog.csdn.net/andrewfan

2
2
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

unity关于lineRender平滑画线问题

使用lineRender的时候需要在摄像机上加上组件linerender 可以调节粗细颜色之类 可以简单下面方法测试 void Start () { lineRenderer = gameOb...
  • shenmifangke
  • shenmifangke
  • 2016-02-01 16:44
  • 5317

【Unity】Unity中MonoDevelop背景颜色改变

文章转载:http://blog.csdn.net/heyuchang666/article/details/52881534 用MonoDevelop开发Unity时,可以适当调一下颜色保...
  • ldy597321444
  • ldy597321444
  • 2016-11-16 18:43
  • 3686

Unity——通过脚本给物体改变颜色

我们可以先创建一个脚本,创建5个Cube,并给改变cube 的颜色为blue,将脚本绑定在摄像机上。using UnityEngine; using System.Collections;public...
  • yy763496668
  • yy763496668
  • 2016-11-02 23:57
  • 13663

Unity Shaders and Effects Cookbook (7-1) 在Surface Shader 中 访问 顶点颜色

在OpenGL中,需要顶点着色器和片段着色器的支持才能进行正确的渲染,在顶点着色器中,每一帧 对 场景中物体的每个顶点都要执行一次处理。如果自己使用OpenGL,需要在C++ 代码读取模型数据,将顶点...
  • cp790621656
  • cp790621656
  • 2016-05-11 01:19
  • 6951

神临的 unity shader 学习之顶点颜色(七)

元旦过去了,神临表示还没有休息够,下次要等到春节了,上班好麻烦,做项目好麻烦,活着也好麻烦,要是能懒着多好呐. 继续写我的shader了,这次是顶点颜色,不得不说这是一个一旦应运纯属便能节约大量资源...
  • qq_38572472
  • qq_38572472
  • 2018-01-03 10:29
  • 33

Unity 对象颜色梯形渐变Shader,可调节

Unity梯形颜色渐变Shader
  • KiTok
  • KiTok
  • 2017-11-22 16:54
  • 518

Unity的基本Shader框架写法&颜色、光照与材质

原文地址:http://blog.csdn.net/poem_qianmo/article/details/40955607 本篇文章中,我们学习了Unity Shader的基本写法框架,以...
  • oSKyTonight
  • oSKyTonight
  • 2014-12-29 18:05
  • 16414

Unity动态生成带碰撞体的LineRenderer

using UnityEngine; using System.Collections;public class DrawPhysicsLine : MonoBehaviour { priva...
  • TreePulse
  • TreePulse
  • 2015-08-21 18:07
  • 1505

Unity3d LineRenderer画线

LineRenderer线渲染器主要是用于在3D中渲染线段,虽然我们也可以使用GL图像库来渲染线段,但是使用LineRenderer我们可以对线段进行更多的操作,例如:设置颜色,宽度等。在这里要注意L...
  • andyhebear
  • andyhebear
  • 2016-02-18 16:28
  • 7179

<Unity3D>Unity3D中LineRenderer的使用

LineRenderer线渲染器主要是用于在3D中渲染线段,虽然我们也可以使用GL图像库来渲染线段,但是使用LineRenderer我们可以对线段进行更多的操作,例如:设置颜色,宽度等。在这里要注意L...
  • zuoyamin
  • zuoyamin
  • 2013-05-31 09:50
  • 20577
    个人资料
    • 访问:87890次
    • 积分:1286
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:1篇
    • 译文:1篇
    • 评论:43条
    关于Andrew
    Unity游戏开发程序员,
    开源游戏引擎Cyclone2D作者,
    我最近在开发一款3D赛车游戏
    热爱图形学、物理学、架构等研究,
    有兴趣的同学加群:528266922。
    博客专栏
    最新评论