[Unity] Simple Shaderlab 1 || uGui用简单shader - 流光

最近经常要给2D游戏写一些新的shader来做特效。比起粒子特效,着色器特效可能更适合UI和2D元素上的表现。

先看一下效果:

关于在shaderlab种实现流光的文章很多,但很少有给UI实现的,并且常常只是Add一层颜色,并没有去表现“光”的效果。

以下是shader全文,后面会介绍一些细节:

 1 Shader "Sprites/Default_Flowlight"
 2 {
 3     Properties
 4     {
 5         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
 6         _Color ("Tint", Color) = (1, 1, 1, 1)
 7         [MaterialToggle] PixelSnap ("Pixel snap", float) = 0
 8
 9         _FlowlightTex ("Flowlight Texture", 2D) = "white" {}
10         _Power ("Power", float) = 1
11         _SpeedX ("SpeedX", float) = 1
12         _SpeedY ("SpeedY", float) = 0
13     }
14
15     SubShader
16     {
17         Tags
18         {
19             "Queue"="Transparent"
20             "IgnoreProjector"="True"
21             "RenderType"="Transparent"
22             "PreviewType"="Plane"
23             "CanUseSpriteAtlas"="True"
24         }
25
26         Cull Off
27         Lighting Off
28         ZWrite Off
29         Blend One OneMinusSrcAlpha
30
31         Pass
32         {
33         CGPROGRAM
34             #pragma vertex vert
35             #pragma fragment frag
36             #pragma multi_compile _ PIXELSNAP_ON
37             #include "UnityCG.cginc"
38
39             struct appdata_t
40             {
41                 float4 vertex : POSITION;
42                 float4 color : COLOR;
43                 float2 texcoord : TEXCOORD0;
44             };
45
46             struct v2f
47             {
48                 float4 vertex : SV_POSITION;
49                 fixed4 color : COLOR;
50                 half2 texcoord : TEXCOORD0;
51                 half2 texflow : TEXCOORD1;
52             };
53
54             fixed4 _Color;
55             sampler2D _FlowlightTex;
56             fixed4 _FlowlightTex_ST;
57             fixed _SpeedX;
58             fixed _SpeedY;
59
60             v2f vert(appdata_t IN)
61             {
62                 v2f OUT;
63                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
64                 OUT.texcoord = IN.texcoord;
65                 OUT.texflow = TRANSFORM_TEX(IN.texcoord, _FlowlightTex);
66                 OUT.texflow.x += _Time * _SpeedX;
67                 OUT.texflow.y += _Time * _SpeedY;
68                 OUT.color = IN.color * _Color;
69                 #ifdef PIXELSNAP_ON
70                 OUT.vertex = UnityPixelSnap (OUT.vertex);
71                 #endif
72
73                 return OUT;
74             }
75
76             sampler2D _MainTex;
77             float _Power;
78
79             fixed4 frag(v2f IN) : SV_Target
80             {
81                 fixed4 c = tex2D(_MainTex, IN.texcoord);
82                 fixed4 cadd = tex2D(_FlowlightTex, IN.texflow) * _Power;
83                 cadd.rgb *= c.rgb;
84                 c.rgb += cadd.rgb;
85                 c.rgb *= c.a;
86                 return c;
87             }
88         ENDCG
89         }
90     }
91 }

由于是从Unity自带shader“Sprites-Default”修改而来,故名字只是在其后加上“-Flowlight”。

其实流程和正常的UV滚动叠加没有什么区别,注意要用UI传入的UV计算纹理坐标。

66  OUT.texflow = TRANSFORM_TEX(IN.texcoord, _FlowlightTex);

之后两张纹理在frag中叠加输出,需要注意的只有一行:

83  cadd.rgb *= c.rgb;

很多shader作者在写流光的时候只是把叠加纹理的颜色+=在了主纹理上,但如果先将叠加纹理乘以主纹理的颜色,就会让暗色变得更暗,更符合光吸收的感觉,再配合Power控制光强度可以更好地表现光。

当然这样一来的副作用就是流光纹理本身的颜色就没有用了,因为变成了只用灰度,毕竟本身目的只是在打光。需要颜色的话可以在这行的下一行乘以自定义颜色,这里就不写了。

以上是需要留意的部分。

具体流程上,在vert中先获得流光纹理的纹理坐标OUT.texflow,而后使用_Time时间参数让纹理坐标随时间偏移,注意偏移操作在顶点着色vert部分进行而不是在片段着色frag,这样不会浪费计算量。

之后在frag中进行叠加将流光纹理与主纹理叠加,注意是c.rgb += cadd.rgb,否则c += cadd会导致透明通道也被叠加上去,对下一步c的预乘透明通道产生影响。

在纹理的制作上,因为是循环滚动,所以为了不会让光出现过度频繁,需要在流光纹理的旁边加上合适宽度的黑色区域,下面是本文开头动图使用的流光纹理。

它在光线纹理(正方形纹理)的左侧加上了等宽的黑色区域,让纹理变为了2x1的宽度,这样再将材质的Tiling改为X:0.5  Y:1就可以让光出现的频率减半了,当然还可以把光线区域在PS再缩小为66%,这样就可以让光线的出现频率变为最初的1/3了(别忘了改Tilling),其他频率以此类推。

下一次会分享一下uGui用的溶解。说是uGui用,其实使用了Sprite Shader的东西都可以用。

时间: 2024-10-11 13:07:29

[Unity] Simple Shaderlab 1 || uGui用简单shader - 流光的相关文章

[Unity] Simple Shaderlab 1 // UI用的简单shader 1 - 流光

最近经常要给2D游戏写一些新的shader来做特效.比起粒子特效,着色器特效可能更适合UI和2D元素上的表现. 先看一下效果: 关于在shaderlab种实现流光的文章很多,但很少有给UI实现的,并且常常只是Add一层颜色,并没有去表现“光”的效果. 以下是shader全文,后面会介绍一些细节: 1 Shader "UI/Unlit/Flowlight" 2 { 3 Properties 4 { 5 [PerRendererData] _MainTex ("Sprite Te

【Unity Shaders】Transparency —— 透明的cutoff shader

本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ========================================== 写在前面 啦啦啦,终于毕业啦~上个月上任了游戏版版主,感觉在毕业前的一个月又给自己找了不少事.自己还

Unity加载模块深度解析(Shader)

作者:张鑫链接:https://zhuanlan.zhihu.com/p/21949663来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 接上一篇 加载模块深度解析(二),我们重点讨论了网格资源的加载性能.今天,我们再来为你揭开Shader资源的加载效率. 这是侑虎科技第59篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨.(QQ群465082844) 资源加载性能测试代码 与上篇所提出的测试代码一样,我们

Unity模拟龙之谷人物行走简单控制

我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作.打击感都挺好的. 今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作很多,我这里只做了简单的walk和run的测试哈,但是感觉也蛮舒服的,哈哈. 期待的效果:鼠标旋转控制视角位置,滚轮控制镜头缩放.点击一次W键为行走,快速点击两次为奔跑. 1.准给工作: 场景中, 一个Camera.一块地皮.一只Cube 2.镜头的缩放和旋转实现: 看下Camera的组件: 再看下Cube的组件: mousel

Unity UGUI 实现简单拖拽功能

说到拖拽,那必然离不开坐标,UGUI 的坐标有点不一样,它有两种坐标,一种是屏幕坐标,还有一种就是 UI 在Canvas内的坐标(暂时叫做ugui坐标),这两个坐标是不一样的,所以拖拽就需要转换. 因为鼠标的移动是屏幕坐标,而 UI 的移动是ugui坐标.转换的方法: RectTransformUtility.ScreenPointToLocalPointInRectangle ( - ); 这个方法可以把屏幕坐标转换成 ugui 坐标.这里我们只需要知道 UI 的坐标和鼠标的坐标是不一样的,他

Unity编程笔录--ulua+PureMVC框架简单热更新使用

ulua+PureMVC框架简单热更新使用 前言: 1:作者官网论坛 首先介绍的是这个框架是一位大牛  骏擎[CP]  jarjin   写的,据说原本是"非常多人不知道怎么使用Ulua,所以搞了个演示Demo",可是这个初衷发生了变化,突然有一个天作者发现非常多人基于这个Demo去做游戏了.这出乎作者的意料. 在此希望这个框架会越来越好. 眼下为止这个框架是全然免费的. 官网地址:http://www.ulua.org/ 近期刚刚开了一个论坛,大家不懂的能够去看看,论坛地址:http

Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画

上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色.顶点坐标等. 这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画. 简单介绍原理: 在顶点函数中,获取到顶点坐标 vertex,然后,求float offsetY = sin(vertex.x) ,然后将 offsetY 加到 vertex.y 上,这样就把原来的平面 ,变成了 正弦 波浪. 然后再使用之前学过的 内置变量 _Time ,算式变为 float offset

Unity中2D和UGUI图集的理解与使用

图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢?准确的说法图集是一张包含了多个小图的大图和一份记录了每个小图id.位置.尺寸等数据的数据文件,一个图集应该对应两个文件,当然也有人把数据集成到图片中,导致看起来只有一张图片(参考自DragonBones的做法). 为什么要用图集? 在GPU已经成为PC.手机等设备的必备组件的现在,把所有显示的绘制操

使用Unity自带的NetWorkView实现简单的聊天系统

众所周知,在游戏中,我们经常会简单带聊天系统.一般,我们常见的有公会聊天,也就是大家熟知的QQ群聊,还有就是私聊,相信大家都懂得.好了, 废话不多扯了,我们开工. 首先,我们来写服务器端的. 老规矩,我们先搭建基本的UI.我们这里仍然使用NGUI.服务器端,我们主要负责显示客户端接入情况和收集全部消息,然后同步给每个客户端. 首先,我们创建一个Sprite,重命名为BackGround,然后为其选择图集和精灵,将其颜色调整为黑色,大小为整个UIRoot.然后,我们创建一个Label,重命名为Ti