Godot 4 的 3D 像素画着色器
有些东西烘焙不进精灵表:整个 3D 关卡、玩家可以随意驾驶的载具、有上百个姿势的 Boss。Pixor 把它的外观写成 Godot 4 着色器,这样这些内容就能实时绘制,和你烘焙的角色使用同样的像素。


在 3D 游戏中得到像素画的两种方式
让 Godot 游戏看起来像像素画,常见的做法有两种。第一种是烘焙:从每个方向渲染角色,做成精灵表,再用 AnimatedSprite2D 播放。第二种是以低分辨率绘制 3D 场景本身,通过着色器给光照分色带、限制颜色并画出轮廓,然后用最近邻过滤放大。搜索“3D pixel art shader Godot”和“Godot 4 post processing pixel art”的人,要的是第二种。
两者各有用处。烘焙的精灵表给你手工般的控制和修饰空间,而且绘制不花任何成本。实时渲染则能处理精灵表装不下的内容:摄像机穿行的关卡、能转向任意角度的汽车、所有东西同时运动的场景。问题是两者很少匹配:精灵来自一条流程,关卡来自另外写的着色器,轮廓、颜色和光照互相不一致。
pxr shader 解决了这个问题:它根据烘焙精灵所用的同一个风格来写 Godot 着色器。
写出着色器
指向一个模型和一种外观,或者一个项目,再指向你的 Godot 项目里的一个文件夹:
pxr shader knight.glb --preset selout --size 64 -o my-game/pixor
pxr shader game.pixor -o my-game/pixor --res res://pixor
-o 是磁盘上的文件夹;--res 是 Godot 眼中的同一个文件夹,即 res:// 路径,当它不是 res:// 加文件夹名时才需要。这个文件夹里会有五个文件:
| 文件 | 作用 |
|---|---|
pixor_look.gdshader |
材质。每个像素取其颜色所属的色阶、所在光照色带的级别以及高光,和烘焙精灵一样,使用调色板自己的颜色。它不受光照着色:外观本身就是光照。 |
pixor_lines.gdshader |
线条,一个屏幕后处理:模型周围空像素上的剪影,以及一个表面在另一个表面前面时的内部线条,使用风格的线条颜色。 |
pixor_view.tscn |
像素网格:一个与精灵同尺寸的视口,用最近邻过滤放大四倍,其中包含 Pixor 的摄像机和线条。 |
pixor_look.gd |
PixorLook.apply($Level) 给某个节点下的每个网格都应用这种外观,同时保留每个材质的颜色和纹理。 |
pixor_shader.json |
尺寸、比例、调色板,以及着色器没有包含的那部分风格。 |
放进你的场景
- 把这个文件夹复制进 Godot 项目,或者用
-o直接写到那里。 - 把
pixor_view.tscn加到你的主场景。它会通过像素网格绘制它所在的 3D 世界,并带轮廓处理。 - 给你的网格加上这种外观。在脚本中,
PixorLook.apply($Level)会给该节点下的每个网格设置材质。手动的话,把pixor_look.gdshader放到网格的材质上。
其他什么都不用设:光照色带、色阶、调色板和线条颜色都已经写进着色器。想改变外观,就在 Pixor 里改,再运行一次 pxr shader。
--view-scale 设定每个美术像素变成多少个屏幕像素(默认 4)。和任何像素画一样,请保持为整数;精灵尺寸指南解释了原因。
实时渲染没有包含什么
实时渲染绘制画面的方式和烘焙的一样,只有三处不同:
- 没有投射阴影。表面有光照和色带,但一个物体不会给另一个物体投下阴影。
- 没有深度差就没有部件线。两个相接的部件,比如手臂上的袖子,只有在一个在另一个前面的地方才会有线。
- 没有整帧步骤。需要读取整帧或比较各帧的步骤,比如清理步骤和标明了这一点的手绘原子,只在烘焙时运行。
每个风格节点都会注明它能否实时运行:pxr nodes --graph style 会在每个节点下打印“in real time: yes”或“not yet”。如果风格的节点图中有无法实时运行的节点,就会被拒绝,并且错误信息会指出该节点。加上 --partial,就会不含那个节点,照样写出其余设置的着色器。
两者并用
最强的组合是两种方式一起用。需要手工修饰、大量帧和精确剪影的角色,烘焙成精灵表(Pixor 用于 Godot 介绍了 SpriteFrames 和接好线的现成场景)。世界、载具以及任何大到或自由到无法烘焙的东西,则通过 pxr shader 绘制。因为两者来自同一个风格,它们共用色阶、色带和调色板,玩家看到的是一个游戏,而不是两个。
如果想让精灵在 2D 场景中对光照做出反应,灯光套件(--export light-kit)会根据法线贴图在 Godot、Unity 或 GameMaker 中为烘焙精灵打光,同时每个受光像素都保持在自己的色阶上;参见符合调色板的光照。手册中的这一节介绍了实时着色器的所有选项。
问题
实时着色器有 Unity 或 Unreal 版本吗?
暂时没有:pxr shader 只写 Godot 4 着色器。对于 Unity 和 GameMaker,Pixor 的灯光套件按调色板自己的级别在引擎中为烘焙精灵打光,每个引擎各有一个着色器。
实时外观和烘焙精灵完全一致吗?
它使用同样的色阶、光照色带、高光和调色板。它不包含投射阴影、没有深度差的相接部件之间的线条,以及读取整帧或比较各帧的步骤,比如清理步骤。
我需要手动设置着色器参数吗?
不需要。外观已经烘焙进着色器文件,视图场景里有摄像机和线条处理,PixorLook.apply 会给某个节点下的每个网格应用材质,同时保留各自的颜色和纹理。