深入了解Unity中LineRenderer与TrailRenderer
LineRender和TrailRender是两个好东西,很多Unity拖尾特效都会使用到它们。一些简单的介绍可以参见官方的API文档。
在这里探讨一下它们具体的渲染方式,而后给出一些Shader以便更好地控制它们。
最终我们可以实现类似这样的一个效果:

接下来,我们先了解LineRenderer。稍后的TailRenderer情况类似。
创建LineRender
LineRender是一个以顶点去控制渲染尺寸和位置的条带,顶点个数和具体坐标我们自己可以完全操控。
首先我们需要建立了一个GameObject,然后添加LineRenderer组件,然后填入一下参数:
其实就是一个沿着X方向延展的一组顶点。然后新建一个材质,并把它拖入Materials。
由于当前你使用的是默认材质,所以目前只能获得以下的样子:
就是一个矩形而已。
修改LineRenderer
首先,我们需要一张资源图片,大概是这样:
这个图片使用PSD制作一下,里面白色部分代表将来要在条带中显露出来的部分,黑色则是透明的部分。只有黑白两种颜色即可。注意要加入通道,即把这个黑白图片在PSD中新建一层透明通道,并且粘贴进去。最后让你的通道看起来是这样:
为什么只要黑白图,不需要颜色?解释一下:
我们用这个素材来构成条带的主要轮廓,而显示的色彩由其它参数控制,所以这里只需要黑白图就可以了。
开始写Shader
属性部分,就是一张贴图就可以了。
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
Tags部分,我们需要设定处于半透明渲染队列,并且设定Alpha混合的模式,就是用最常见的Alpha混合的模式即可。
Tags { "RenderType"="Transparent" "IgnoreProjector"="True" "Queue"="Transparent"}
LOD
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,修改之前的材质。最终这个条带变成这样:
完整的LineRenderer的Shader
Shader "AndrewBox/LineRenderer" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Transparent" "IgnoreProjector"="True" "Queue"="Transparent"}
LOD
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) = (,,,)
}
最后,在表面着色器中进行相应的修改
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所在的GameObject的旋转,代码相对简单。(BaseBehavior类的实现可以参见我的其它文章)
public class TrailRendererGen : BaseBehavior
{
[SerializeField][Tooltip("旋转角速度")]
protected float m_angle=;
protected override void OnInitFirst()
{
} protected override void OnInitSecond()
{
} protected override void OnUpdate()
{
m_transform.Rotate(Vector3.forward, m_angle*Time.deltaTime);
}
}
完整的TailRenderer的Shader
Shader "AndrewBox/TrailRenderer" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_MainCol ("Self Color Value", Color) = (,,,)
}
SubShader {
Tags { "RenderType"="Transparent" "IgnoreProjector"="True" "Queue"="Transparent"}
LOD
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 _MainCol;
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);
//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;
}
ENDCG
}
FallBack "Diffuse"
}
总结
最终,我们可以完整控制两种Renderer的渲染了,最重要的事情再说一遍,就是它们的Color设定都写入了顶点颜色,我们可以通过读取顶点颜色来完成自己想要的渲染效果。
本页完整资源请在我的CSDN博客中获取:http://blog.csdn.net/andrewfan
本文为博主原创文章,欢迎转载。请保留博主链接http://blog.csdn.net/andrewfan
深入了解Unity中LineRenderer与TrailRenderer的更多相关文章
- NGUI研究院之在Unity中使用贝塞尔曲线(六)[转]
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...
- Unity中Mesh分解与边缘高亮加上深度检测
一个比较简单的需求,不过遇到些坑,记录下. 房间有多个模型,每个模型可能多个SubMesh,点击后,需要能具体到是那个SubMesh,并且在这个SubMesh上显示边缘高光,以及能个性这单个SubMe ...
- 在Unity中使用贝塞尔曲线(转)
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...
- NGUI研究之在Unity中使用贝塞尔曲线
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天由于工作的原因须要将贝塞尔曲线加在project中.那么我迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的随意角度的曲线,这两个点一 ...
- 【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现
RT,马三最近在参与一款足球游戏的开发,其中涉及到足球的各种运动轨迹和路径,比如射门的轨迹,高吊球,香蕉球的轨迹.最早的版本中马三是使用物理引擎加力的方式实现的足球各种运动,后来的版本中使用了根据物理 ...
- Unity中做放大镜 效果
孙广东 2015.8.16 事实上和 小地图都几乎相同了. 还是要借助 还有一个相机 目的: 这篇文章的主要目的是 要给你一个想法 怎样做放大境效果 . 在unity中能够简单的实现放大镜效果啊 ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
- 在Unity中使用UGUI修改Mesh绘制几何图形
在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...
- Unity中使用WebView
Unity中使用WebView @(设计) 需求,最近游戏中需要引入H5直播页面和更新比较频繁的赛事页面,需求包括:加密传参数.和Unity交互,在Unity框架下其实有几种方案: 内置函数Appli ...
随机推荐
- jquery $提示缺少对象$提示缺少对象
jquery $提示缺少对象 项目中存在不同版本的jquery,有1.4也有1.2, 之前运行项目不会报错 " $提示缺少对象 ",但是我的IE9重置之后就报错,从网上找了一大堆, ...
- Java解析JSON文件的方法 (二)
assets文件夹资源的访问 assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式读取文件. 1. 先在Activity里面调用g ...
- win8.1 64位+oracle11g R2 64位 +powerdesigner破解版 64位+PL/SQL
安装时搜索了很多帖子,很多就是复制粘贴(完全不需要什么IP,host),有的版本不对,有的版本太老,今天决定贴出自己的处女贴 oracle的安装很简单,不需要说什么了,PL/SQL真是恶心死 orac ...
- Windows 7 Professional安装多语言包
本文出自 "王春海的博客" 博客,请务必保留此出处http://wangchunhai.blog.51cto.com/225186/223635 下载了Windows 7 Prof ...
- ExportExcel
package cn.com.jansh.core.util; import java.awt.print.Book; import java.io.BufferedInputStream; impo ...
- tomcat 修改网站路径(Java之负基础实战)
1.找到server.xml 在tomcat安装路径/conf/server.xml 2.搜索webapps 添加 <Context path="" docBace=&quo ...
- PHP新手之学习类与对象(3)
四.访问控制 对属性或方法的访问控制,是通过在前面添加关键字 public.protected 或 private 来实现的.由 public 所定义的类成员可以在任何地方被访问:由 protecte ...
- js与php传递参数
这个问题在网页开发时经常遇到,其实解决办法非常简单,就是几行代码的事,不过各种js.php书上都没有,百度下来也乱七八糟的,有的能用,有的不能用.小编遇到这问题时认认真真研究了一上午,研究出一点心得, ...
- Java 原型模式
http://www.cnblogs.com/itTeacher/archive/2012/12/02/2797857.html http://www.cnblogs.com/java-my-life ...
- Spring4.14 事务异常 NoUniqueBeanDefinitionException: No qualifying bean of type [....PlatformTransactionManager]
环境为Spring + Spring mvc + mybatis:其中Spring版本为4.1.4 spring配置文件: <?xml version="1.0" encod ...