用着色器处理AI绘制的角色关键帧素材

群友编写了个还不错的用AI生成角色逐帧动画的工作流。这很好,这样一来,制作2D游戏就能更加简单吧。

不过,还是有点问题的。生成的图像,第一,发糊,第二,不支持alpha通道。我必须手动指定生成绿幕,然后抠掉绿幕。才可以。

幸运的是,着色器可以派上用场。更幸运的是,Godot总算支持REGION_RECT了。这是什么意思呢?意思是,以前无法直接给着色器使用的AtlasTexture的Region,以及包含多个Image的SpriteSheet,现在也可以通过REGION_RECT所得到的信息,正确定位局部UV了!写游戏从来没有如此简单过!

以防万一,我在这里留下我的着色器代码,以免以后要用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
shader_type canvas_item;

uniform vec4 ColorToExclude :source_color = vec4(1.0); // 背景,可外部分配
uniform float ExcludeThreshold = 0.8; // 分割阈值。当与目标绿幕颜色点积大于阈值时则视作绿幕,进行抠图
uniform vec2 RenderRegion =vec2(0.98); // 有效渲染范围。裁剪外部

// 局部块UV转全局UV
vec2 region_to_texture_uv(vec2 uv, vec4 region_info) {
return uv * region_info.zw + region_info.xy;}

// 全局UV转局部块UV
vec2 texture_to_region_uv(vec2 uv, vec4 region_info) {
return (uv - region_info.xy) / region_info.zw;}

void fragment() {
// 进行抠图,抠掉绿幕
if (dot(normalize((COLOR.rgb)), normalize (ColorToExclude.rgb)) >= ExcludeThreshold )
COLOR=vec4(0.0);

vec2 localUV = texture_to_region_uv(UV, REGION_RECT);

// 非渲染区域
if ((localUV.x < (1.0-RenderRegion.x)/2.0 ) || (localUV.x > (1.0+RenderRegion.x)/2.0)){
COLOR=vec4(0.0);
}

if ((localUV.y < (1.0-RenderRegion.y)/2.0 ) || (localUV.y > (1.0+RenderRegion.y)/2.0)){
COLOR=vec4(0.0);
}
}


至于效果?反正我觉得还行。

我没有进行更进一步的降噪/后处理/像素化了。太久没碰着色器,感觉自己仿佛修为散尽了,唉。