【Unity3D】 Unity Chan项目分享
写在前面
之前的一个博文里分享了日本Unity酱的项目,如果大家有去仔细搜Unity酱的话,就会发现日本Unity官方还放出了一个更完整的Unity酱的项目,感觉被萌化了!(事实上,Unity日本经常会分享一些开源项目,要常关注github~)
一些效果
项目里还有有一些特效实现可以借鉴下的~
MusicPlayer
这个项目里的特效有个最大的特点就是,特效会根据音效做出反馈。这个功能主要是通过作者的另一个开源插件Reaktion来实现的(Keijiro Takahashi是个多产哥,这哥们感觉一年时间都用在写开源项目了,一年有几十的repositories。。)只可惜文档都不是很全,大多需要自己去稍微读一下源码。Keijiro曾经为Reaktion写过一版文档,不过看来没有维护下去……
想要让Reaktion工作就需要有三个关键部分,音频注入器Injector、音频核心处理器Reaktor以及接收信号的装置Gear,Injector把音频信号传递给某个Reaktor,然后场景里所有的Gear会监听某个Reaktor的输出,它们之间的链接都是通过GenericLink类实现的。也就是我们需要两个links,一个link(InjectorLink类型)负责让每个Reaktor找到一个Injector,一个link(ReaktorLink类型)负责让每个Gear找到一个Reaktor。它们都有四种链接模式(在GenericLink.cs中被定义):Not Bound,即不绑定输入;Auto Bind,找到离该物体最近的那个输入器(先在自身身上找,不然再找父亲,不然再找儿子,不然再找全场景);Bind By Reference则可以让我们直接拖一个输入的引用;Bind By Name则会在场景里找名字为该字符串的特定输入。
因此,整个过程大概就是:
- 在场景里添加一个AudioSource,然后在同一个物体上添加AudioInjector.cs,以及添加Reaktor.cs,保证该Reaktor可以找到这个Injector(可以直接把模式设成Auto Bind就会直接找到自身绑定的这个Injector了)。我们可以调整Reaktor上的属性来对音频信号进行调整。
想要接收声音信号的话可以在自定义脚本中声明Reaktion.ReaktorLink类型的变量。例如:
public Reaktion.ReaktorLink spectrum1;
public Reaktion.ReaktorLink spectrum2;
public Reaktion.ReaktorLink spectrum3;
public Reaktion.ReaktorLink spectrum4;声明了四个音频来源,那么在面板上就是这样的结果:
我们可以通过不同的链接模式来为它们绑定不同的Reaktor,如上所示。然后在代码里通过Reaktion.ReaktorLink.Output就可以直接得到输出信号了。
- 作者为我们内置了一些常见的信号功能,例如把信号传递给材质来设置属性值(MaterialGear)、设置Transform属性(TransformGear)、设置粒子系统属性(ParticleSystemGear)等。我们可以直接使用这些内置的脚本(都在Reaktion/Gear文件夹下)。
到这个具体项目里,所有的Injectors和Reaktors都在名为MusicPlayer的prefab中。它的结构如下:
MusicPlayer包含了五个子物体,其中四个子物体(Spectrum 1,Spectrum 2等)各包含了一对Injector和Reaktor,之所以有四个是因为作者想要使用不同的过滤器(BandPassFilter.cs)来过滤同一个音频,得到四种音频信号。注意到每个Spectrum上的AudioInjector上的Mute属性被勾选了,这意味着虽然它们身上都有一个AudioSource但并不会发出任何声音。真正的音乐是由第五个子物体Main负责发出的。
舞台光柱、台标、光圈和环状大轨道
这个项目里很多效果都会随着音效变化,变化比较相似的是舞台后面光柱(Pillars)、Unity Chan的台标(Ribbon)、和环状大轨道(Orbit Inner和Orbit Outer)。
这些都是使用MaterialGear来配合材质的。下面是光柱(Pillars)的面板:
它使用了3个材质,其中第二个材质YellowSurface和第三个材质RedSurface使用了自定义的自发光Custom/Untextured Emmisive Surface,这个shader其实就是一个有最简单自发光效果的surface shader,它的自发光大小是靠属性_Amplitude控制的:
o.Emission = _Emission * _Amplitude;
为了让自发光大小随着音乐变化,这里使用了两个MaterialGear,分别对应一个材质。为了让两个材质的变化不要完全一致,这里把它们的Reaktor来源设成了不同的模式。MaterialIndex用于指定是作用于当前的第几个材质,后面的TargetType和TargetName是设置的属性,FloatCurve是可以让我们进一步对输入信号进行加工。
舞台音响
舞台音响也是个很有特色的效果。它的音波(其实就是很多圆圈)会随着音乐忽大忽小。
这个就是通过AnimatorGear来触发Animator里面的状态来实现的。
酷炫的地板
Unity Chan脚下的地板(Visualizer)特效很是酷炫,一会画圈圈一会画蜂巢的,还能随着音乐变化,很有意思。
Visualizer大概是这里面最复杂的一个。作者不仅为它自定义了音频信号处理脚本,它使用的shader也比较复杂,还用到了额外的渲染纹理来实现反射效果(可以从下图的材质上看到有些许舞台反射效果)。
Visualizer.cs脚本还是比较简单的,它声明了四个用于连接Reaktor的ReaktorLink,分别对应了MusicPlayer中的四个Reaktor。每次Update时,它从ReaktorLink.Output得到四个音频信号,再在OnWillRenderObject中、在渲染该物体之前,把信号传递给自己的材质,并找到渲染物体的摄像机,把该摄像机的视角-投影矩阵的逆矩阵传给材质,这主要是为了根据反射的深度图重建每个点的世界坐标,再根据坐标的高度值(y)来计算一个反射程度的衰减值。
另一个脚本MirrorReflection比较复杂,负责渲染反射的彩色纹理和深度纹理。有兴趣的可以仔细看下,大概就是在地板附近放一个摄像机,然后设置它的各个矩阵和状态,得到两张渲染纹理,再传递给材质。
Visualizer.shader也比较复杂,感觉性能堪忧,竟然还是用surface shader写的。Anyway,它的那些光圈和格格的效果全是代码实现的,然后添加到自发光变量上。除了上面的自发光颜色,还添加了舞台反射的颜色,反射点距离地板越远,反射强度越弱。此外,还使用了模糊技术,取了9个采样点平均后作为最终的反射颜色。计算量还是很大的,优化做的也不是很好,采样坐标的计算等都放到了surf里计算,而且还有一次矩阵乘法。感兴趣的需要自己优化下了。
舞台前灯
Unity Chan的舞台前灯(场景里的Front Lights和Front Lights Beam物体)虽然不会随音乐变化,但它用的shader也挺有意思的。Front Lights的颜色(其实就是一个使用了自发光的surface shader)会随着时间变化,这是靠Animator实现的。而它发出的光(Front Lights Beam)是靠一个椎体实现的,而且看起来好像有飘渺的效果(也有Bloom特效的功劳),这主要是靠Custom/Light Beam来实现的。这个shader是一个双面半透明的vf shader,包含一个主颜色(控制光的整体颜色)、渐变纹理(控制光由强到弱)、两张噪声纹理(控制光的移动效果)、噪声程度和噪声速度(控制噪声的大小和平移速度)。有一些有趣的法线:
计算噪声纹理的采样坐标时,作者使用了世界空间位置的xy来让各个前灯的光都不一样:
o.uv1 = wp.xy * _NoiseScale.xy + _NoiseSpeed.xy * _Time.y;
计算光的透明度时,作者还使用了一个衰减因子就是观察方向和法线的角度,当角度在某个区间范围内该衰减因子为0。这样做的目的是为了让光锥的边界更加平滑,这一点很重要。
float falloff = max(abs(dot(camDir, normal))-0.4, 0.0);
falloff = falloff * falloff * 5.0;
舞台大屏幕
另一个挺好的就是后面的大屏幕(Back Screen)。
这个肯定是通过另一个摄像机渲染一张渲染纹理得到的,但上面的屏幕黑条效果使用了Custom/Back Screen的shader。
shader还是很简单的,就是在主纹理上添加了一个条状纹理,并使用sin配合lerp函数添加一个不断闪烁的效果:
float4 frag(v2f i) : COLOR
{
float4 color = tex2D(_MainTex, i.uv0);
float amp = tex2D(_StripeTex, i.uv1).r;
amp = _BaseLevel + _StripeLevel * amp;
float time = _Time.y * 3.14f * _FlickerFreq;
float flicker = lerp(1.0f, sin(time) * 0.5f, _FlickerLevel);
return color * (amp * flicker);
}
其他
还有一些就不一一写了。比如摄像机的运动很飘逸啊,这是靠CameraSwitcher.cs在很多个位置之间不断lerp得到的;激枪(Laser)发射的效果,是靠Animator实现的;各种撒花(Confetti),是粒子系统。
写在最后
这个项目还有一个特点就是基本所有的物体都是后来加载到场景的,运行前整个场景基本是空的,作者说这样有助于多人协作。
关于作者之一的Keijiro Takahashi再多说几句,Keijiro之前在索尼工作了十年,然后跳到了Unity日本,期间做了大量关于Unity的开源项目,有一些还是很不错的~
【Unity3D】 Unity Chan项目分享的更多相关文章
- 6个Unity 开源项目分享!
http://gad.qq.com/article/detail/38279?sessionUserType=BFT.PARAMS.249034.TASKID&ADUIN=991655778& ...
- 手机游戏渠道SDK接入工具项目分享(二)万事开头难
一般接到任务后程序员们通常都开始着手进行技术调研了,但我这活是项目负责人.还有一大堆事情要先期准备,没人能帮忙. 一.人力配置 考虑的之前已经有一波人搞了大半年,但没有起色,先期也没有太大人力需求,所 ...
- 【Unity Shader】Unity Chan的卡通材质
写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...
- 手机游戏渠道SDK接入工具项目分享(三)拨开云雾是个坑
一直在纠结是先写框架设计还是先写掉过的坑,最后本这娱乐大众的态度先写掉过的坑让大家乐呵下. 项目开发过程中遇问题无数,回顾下8个大坑照成了项目一定程度上延期甚至返工. 项目一开始几个人把现有3家主流的 ...
- unity 嵌入 百度分享 与 游戏内购物 iap
原地址:http://blog.csdn.net/u012085988/article/details/18268869 最近老板让在unity项目里实现分享与内购功能,还要ios和android两个 ...
- 第9期Unity User Group Beijing图文报道:《Unity实战经验分享》
时间来到了金秋九月,北京UUG活动也来到了第九期.本次活动的主题为<Unity实战经验分享>,为此我们邀请了3位资深的行业大神.这次我们仍然在北京市海淀区丹棱街5号微软大厦举行活动,在这里 ...
- 手机游戏渠道SDK接入工具项目分享(一)缘起
#剧情章节 # 上周刚结束一个外包的项目,开发手机游戏渠道SDK聚合接入工具的,现在有空回顾整理一下这个项目开发过程,因涉嫌商业秘密不会提供项目代码,只谈下开发思路和掉过的坑. 本人多年从事手机互联网 ...
- 项目分享五:H5图片压缩与上传
一.简介 图片的压缩与上传,是APP里一个很常用的功能.我们来年看 ChiTuStore 是怎样做的.相关文件 App/Module/User/UserInfo.html,App/Module/Use ...
- 项目分享二:APP 小红点中数字的处理
小红点,是 APP 中最常见的一个功能,我们先来看一下面的案例,下图中,待评价的商品有 2 个,点击“评价晒单”按钮进行评价后,那么待评价数量应该变成 1,那么这个功能是如何去实现的呢? 一般来说,实 ...
随机推荐
- React Native(十五)——RN中的分享功能
终于,终于,可以总结自己使用RN时的分享功能了-- 为什么呢?且听我慢慢道来吧: 从刚开始接触React Native(2017年9月中旬)就着手于分享功能,直到自己参与公司的rn项目开发中,再到现在 ...
- 用js来实现那些数据结构06(队列)
其实队列跟栈有很多相似的地方,包括其中的一些方法和使用方式,只是队列使用了与栈完全不同的原则,栈是后进先出原则,而队列是先进先出(First In First Out). 一.队列 队列是一种特 ...
- Spring AOP异常捕获原理
Spring AOP异常捕获原理: 被拦截的方法,须显式的抛出异常,且不能做任何处理, 这样AOP才能捕获到方法中的异常,进而进行回滚. 换句话说,就是在Service层的 ...
- mysql如何选择合适的数据类型1:CHAR与VARCHAR
CHAR和VARCHAR类型类似,都用来存储字符串,但它们"保存"和"检索"的方式不同.CHAR属于"固定长度"的字符串,而VARCHAR属 ...
- [LeetCode] K Empty Slots K个空槽
There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one ...
- [LeetCode] Single Element in a Sorted Array 有序数组中的单独元素
Given a sorted array consisting of only integers where every element appears twice except for one el ...
- bzoj 4830: [Hnoi2017]抛硬币
Description 小A和小B是一对好朋友,他们经常一起愉快的玩耍.最近小B沉迷于**师手游,天天刷本,根本无心搞学习.但是 已经入坑了几个月,却一次都没有抽到SSR,让他非常怀疑人生.勤勉的小A ...
- [LOJ 6249]「CodePlus 2017 11 月赛」汀博尔
Description 有 n 棵树,初始时每棵树的高度为 H_i,第 i 棵树每月都会长高 A_i.现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不 ...
- 【BZOJ1060】【ZJOI2007】时态同步
Description 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3-.进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板 ...
- ●BZOJ 2393 Cirno的完美算数教室
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2393 题解: 容斥原理,暴力搜索,剪枝...和 [Scoi2010 幸运数字] 一样的(只是 ...