作者meowyih (meowyih)
看板GameDesign
标题[程式] 做出发光效果 (用shader/Godot)
时间Fri Jul 2 21:21:25 2021
这篇的图片和范例出处是
GDQuest shader secret 的 BlurGlowDemo 连结
https://github.com/GDQuest/godot-shaders
算是读书报告吧?
目标是用 shader language
在下面的图片背後加上神秘的光芒
https://i.imgur.com/5RC7n1X.png
[Step 1]
首先用下面的 shader 做个剪影
shader_type canvas_item;
uniform vec4 glow_color : hint_color = vec4(1.0);
void fragment() {
vec4 color = texture(TEXTURE, UV);
COLOR = vec4(glow_color.rgb, color.a);
}
就把每个 UV 颜色
换成预计要的发光色 glow_color
https://i.imgur.com/YG1EwuM.png
[Step 2]
再来用高斯乱数杂讯
对 X 轴做模糊化
(ex: blur_scale = (4,0))
shader_type canvas_item;
const float SAMPLES = 71.0;
const float PI2 = 6.283185307179586476925286766559;
uniform vec2 blur_scale = vec2(1, 0);
float gaussian(float x) {
float x_squared = x*x;
float width = 1.0 / sqrt(PI2 * SAMPLES);
return width * exp((x_squared / (2.0 * SAMPLES)) * -1.0);
}
void fragment() {
vec2 scale = TEXTURE_PIXEL_SIZE * blur_scale;
float weight = 0.0;
float total_weight = 0.0;
vec4 color = vec4(0.0);
for(int i=-int(SAMPLES)/2; i < int(SAMPLES)/2; ++i) {
weight = gaussian(float(i));
color += texture(TEXTURE, UV + scale * vec2(float(i))) * weight;
total_weight += weight;
}
COLOR = color / total_weight;
}
https://i.imgur.com/HixMdyz.png
[Step 3]
然後模糊化的图形基础上
用同样的方法对 Y 轴做模糊化
(ex: blur_scale = (0,4))
https://i.imgur.com/66R0DyM.png
需注意的地方是,
这要分二个步骤做,
一次同时模糊化 X/Y
结果是如下的类 shear matrix 的效果
(ex: blur_scale = (4,4))
这不是我们要的
https://i.imgur.com/tMR3shc.png
[Step 4]
最後,
用下面的 shader 把
1. 一开始的剪影 (prepass_texture)
2. 模糊化的影像 (blur_texture)
3. 机器人的原图 (TEXTURE)
三个合体,产生最後的图
shader_type canvas_item;
uniform sampler2D prepass_texture;
uniform sampler2D blur_texture;
uniform float glow_intensity;
void fragment() {
vec4 color = texture(TEXTURE, UV);
vec4 prepass = texture(prepass_texture, UV);
vec4 blurred = texture(blur_texture, UV);
vec3 glow = max(vec3(0.0), blurred.rgb-prepass.rgb);
vec3 out_color = color.rgb + glow.rgb * glow_intensity;
COLOR = vec4(out_color, clamp(out_color.r + out_color.g + out_color.b, 0,
1));
}
https://i.imgur.com/9TQmsVq.png
如果拿掉上面的机器人图长这样
https://i.imgur.com/39nwpiQ.png
完成了
更改剪影颜色可以改光的颜色
更改最後的 glow_intensity 或模糊化的 blur_scale
可以更改光晕或亮度
==================
然後是 Godot 实作相关
当 shader 里要取得前几个步骤的图片的像素,
需要用 ViewPort Texture。
所以范例里做剪影用了一个 viewport,
模糊化X/Y各用一个 viewport,
最後合体也用了一个 viewport,
然後因为 shader 或 Godot 需要,
每个 ViewPortContainer 要改 size
然後 viewport 要改
1. size
2. transparent_bg = true
3. Usage = 2D
4. Update Mode = Always
然後 viewport 需要用 ViewPortContainer (VPC) 包起来
因此档案架构像是这样
+Blur_Y (VPC, 模糊图)
+ viewport
+ Blur_X (VPC)
+ viewport
+ Prepass (VPC)
+ Sprite (机器人图)
+MainView (VPC, 合体)
+ viewport
+ Sprite (机器人图)
范例看起来很复杂,
不过做的事就上面写的那些
=================
如果到 Youtube 上找 Godot 2D Glow Effect,
会找到好几个用
WorldEnvironment -> Glow 来做发光的范例,
viewport 里面可以加独立的 Environment
用里面的 Glow 效果做出来的长相是
https://i.imgur.com/q9He3K3.png
你可以看出来
虽然都叫 Glow
但这是完全不同的效果
如果想要类似的效果
我预想是可以先用 shader 做剪影
再对剪影套用 WorldEnvironment Glow,
再盖上原图的作法
不过这部分是我猜想的
实验部份我就不做了
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.231.97.136 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1625232088.A.011.html
※ 编辑: meowyih (36.231.97.136 台湾), 07/02/2021 21:23:39
※ 编辑: meowyih (36.231.97.136 台湾), 07/03/2021 10:08:45
1F:推 tzouandy2818: 推认真 07/03 16:31
2F:推 MaxWei: 推,很清楚的步骤,感谢分享 07/04 11:03
3F:推 johnny94: 讲学推 07/04 13:07