作者meowyih (meowyih)
看板GameDesign
标题[程式] Godot做2D冲击波效果的几种做法
时间Thu May 6 19:36:15 2021
说真的这版也太冷清了,
隔壁版每天上百个人在吵台湾为啥做不出ACG产业,
真的开来讨论实作ACG的版一个星期才一篇文章,
实在让人有点想苦笑 XD
人气那麽低,让我来灌个水吧,
如果图片网址太长开不了可以看这里
https://www.yhorng.com/blog/?p=384
这篇是要写我知道做
2D 冲击波 (shockwave)
的几种方法。
冲击波最常在爆炸时当辅助特效用,
有时会在动作游戏的收刀效果看到,
就是一个扩散的圆环表现出空气震波的感觉,
下面会列出三种(?)不同的实作方法。
方法A: 将单一图片放大
先用 Paint.NET 画出白色圆形,
背景是透明色的单一图片,可以长得像下面。
https://www.yhorng.com/blog/wp-content/uploads/2021/05/shockwave-edge.png
Paint.NET 画这类图的时候,有几个小诀窍。
- 用 shift + eclipse shape 可以画圆
- 用 plug-in Effect -> Align Object 将物件置中
接下来有二种做法。
比较麻烦的做法是建立 Sprite Node,
将 Texture 指定成上面的图片,
开启 GDScipt,
在 func _process(delta) 依时间改变 scale.x / scale.y。
简单 (不用GDScript) 的作法
是建立 Particle2D Node
1. 指定 Texture
2. Amount: 1
3. One Shot: true
4. Physical Material 建立 Paritcle Material
并将 Gravity 和 Directure 都设定为 0
5. Particle Material -> Scale -> Scale Curve
加入随时间变化的scale曲线图并从小拉到大
要让画面漂亮点,
可以更改 Color -> Color Curve 更改透明度。
或是 Hue Variation 改成红绿紫火焰效果。
https://www.yhorng.com/blog/wp-content/uploads/2021/05/ezgif-7-b8b9a3353a57.gif
图片解析度很差,抱歉。
方法B: 粒子系统 (Particle System)
先做一个光球,
用 Paint.NET 就是做一个白色圆形,
然後用 Effect -> Blurs -> Guassian Blur 模糊化,
素材自己做,版权不用愁。:)
https://www.yhorng.com/blog/wp-content/uploads/2021/05/spotlight_1_alpha_brightness.png
建立 Particle2D Node,
指定 Texture,Physical Material -> Particle Material,
然後 Particle Material 设定:
- explsion = 1 (所有粒子同时射出)
- 建立 Particle Material
- 关掉 Gravity
- Direction x, y, z = 0
- Direction -> Spread = 180 (朝四周发射出去)
- Amount 设定大一点
https://www.yhorng.com/blog/wp-content/uploads/2021/05/ezgif-7-3ecad24018b8.gif
要调整速度,
可以从 Initial Velocity (初始速度),Damping (阻泥)。
如果希望颜色越来越透明就改 Color -> Color Curve。
希望有帅气的光晕可以从 Hue Variation 和 Color 透明色着手。
方法C: 着色器 (Shader)
https://www.yhorng.com/blog/wp-content/uploads/2021/05/ezgif-7-9e631a6b5967.gif

下面的 shader code 并没有直接在画面上画东西,
而是用画面上已经有的像素去取代目前的像素,
所以没背景是看不出效果的,
因此上图借了个背景用。
用着色器做出的冲击波其实跟做水波作法是一样。
1. 在需要做效果的最上层的 Node
(需要是 CanvasItem Node)
2. 加入 Material -> Shader Material -> Shader
点击开启 shader language editor。
3. 开始写 shader language
<code>
shader_type canvas_item;
uniform float force = 0.0;
uniform vec2 center = vec2(0,0);
uniform float size = 10;
uniform float thinkness = 0.01;
void fragment()
{
float ratio =
TEXTURE_PIXEL_SIZE.x / TEXTURE_PIXEL_SIZE.y;
vec2 scaledUV = ( UV - vec2(0.5, 0.0) )
/ vec2( ratio, 1.0 ) + vec2(0.5, 0.0);
float mask =
( 1.0 - step(size, length( scaledUV - center ))) *
step( size - thinkness, length(scaledUV - center ));
vec2 disp = normalize(scaledUV - center) * force * mask;
COLOR = texture(TEXTURE, UV - disp);
}
</code>
Shader language 请看其他教学,
那是显卡用的语言,简单的说:
- 每一个 pixel 会 call fragement() 一次。
- uniform 跟 GDScript 的 export 一样,
会在编辑器 Node Panel 看到该参数,
也可以在GDScript runtime 修改。
- 显卡不适合做 condition 判断 (if/while/for),
所以在 code 中是看不到的,比大小时用 step()。
- UV 座标指的是假设整个画布长宽都是 1.0
(不管画面是否真的是 1:1),
该 pixel 的位置会在哪,正中间就是(0.5,0.5)。
- scaledUV 是参考 ratio 算出的 UV
(因为 shockwave 是圆的,不是椭圆)。
- mask 是一个甜甜圈,
在圈圈里的 pixel 我们才会改值 (disp > 0)
- disp 距离中心点越远数值就越大。
- COLOR = 是修改目前 pixel 的颜色
- texture(TEXTURE, UV) 是取得
位在UV座标的 pixel 颜色
然後开启 Node 的 GDScipt,
在执行期间更改 shader uniform parameter 的方法如下。
<code>
# increase size over time
var size = 0.0
material.set_shader_param("size", size)
</code>
虽然效果上 shader 做的最酷,single image 看起来很2D古风 (?),但是这跟游戏风格
有关,太写实也不见得好。
方法4: 其他方法
还有一种方法是覆写 Node2D 的 func _draw(),
利用 draw_circle() 自己画。
但是都用 Game Engine 了还自己画有点找麻烦的感觉。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.163.109.66 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1620300978.A.289.html
1F:推 ritud: 感觉比几年前更冷清,不过大势所趋好像也没有办法。 05/06 21:02
2F:推 oopFoo: 也许一直没有开放新帐号?新血还是蛮重要的。 05/06 23:05
3F:→ oopFoo: 推教学 05/06 23:06
4F:→ grezod: 没办法 台湾想做游戏还真没太多选择 05/07 02:40
5F:→ grezod: 明明没资源的小岛国更该以软体这种创意产业为主 05/07 02:42
6F:推 WJAider: 我平日使用的任何软体产品仔细想了下,除了 ptt 相关以外 05/07 07:22
7F:→ WJAider: 还真没有台湾或者更小的国家生产的... 05/07 07:23
8F:→ WJAider: 完全被大国软体公司垄断了 :( 05/07 07:23
9F:推 a82611141: 推 05/07 07:28
※ 编辑: meowyih (1.163.109.66 台湾), 05/07/2021 07:55:31
10F:推 dreamnook: 05/07 09:03
11F:推 NDark: Notepad++ 表示... 05/07 09:10
12F:→ triplee: 现在的生态不比以往 我是认为即使开放注册也改变不了多少 05/07 09:47
13F:推 tzouandy2818: 认真好文 帮推推 05/07 11:27
14F:推 iLeyaSin365: 发表意见 > 去实际解决 05/07 15:01
15F:推 newhandfun: 我觉得还是因为这业界太劝退了 05/07 18:09
16F:→ newhandfun: 不然做游戏虽然累但真的蛮有趣的 05/07 18:09
17F:推 kingroy: 业界整体只有少数赚钱,投入成本也很保守,很难有改善 05/07 21:02
18F:→ kingroy: 同样技术应用在制造业的领域还比较赚 05/07 21:03
19F:推 LayerZ: 推个,不过这边之前有新人来如果不是技术领域,通常都是 05/08 00:45
20F:→ LayerZ: 先洗脸..(被拖走 05/08 00:45
21F:→ LayerZ: 创意要做出规模也是需要资源的关系吧 05/08 00:46
22F:→ LayerZ: 待过传产,跟有在冲市场的,一边是闭着眼睛做,然後闭着投 05/08 00:48
23F:→ LayerZ: 就想闭着眼睛回收,另一边是边做边冲就边投资源测风向,但 05/08 00:49
24F:→ LayerZ: 创意就少了... 05/08 00:49
25F:推 vsepr55: 这里是劝退流啊 05/08 01:00
26F:→ vsepr55: 有兴趣的去玩game jam想点子实在== 05/08 01:00
27F:推 oopFoo: 游戏环境不好,国内外都一样。但台湾环境最不优 05/08 08:11
28F:推 ManInBlack: supercell rovio都是芬兰出来的啊 05/08 16:35
29F:→ ManInBlack: 也算小国吧,查一下人口我们一半都不到 05/08 16:35
30F:推 NDark: 楼上谈这个已经落後十年. 05/08 18:22
31F:→ NDark: rovio都已经走完生命周期 05/08 18:22
32F:推 NX9999: 推推~推一下找时间有空练习@@ 05/10 08:06
33F:推 ManInBlack: 啊确实,但这几年还是有看到蛮多小型游戏工作室的 05/11 12:10
34F:推 WJAider: 小型很多啦,但小国游戏工作室就不多惹 05/12 02:29
35F:→ linaomasa: 就一堆不会提升自己的制作人 05/13 19:16
36F:推 SecondRun: 没办法啊 想做游戏要不就出钱要不就出技术 05/14 01:34
37F:→ SecondRun: 什麽都没有的还是当个玩家比较开心啦 05/14 01:34
38F:推 BIGbirddy: Shader那部分有点难懂,算uv 那段,求j4 05/14 19:36