You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
2D 游戏程序中最重要的是管理图片,通常也叫 sprite (精灵)。
传统的做法是把 sprite 离线预先打包装箱在一大张贴图上。因为,如果每个 sprite 占用一张 GPU 贴图的话,性能会非常低。而且,GPU 贴图的 handle 往往还是有限的,如果游戏采用序列帧动画的话,sprite 数量是巨大的(但每个 sprite 尺寸并不大)。
离线打包装箱增加了开发流程的复杂度。作为开发者,我更希望可以单张 png 图片来管理 sprite 。只有在存放序列帧动画时,一系列 sprite 有相关性时,才把多张 sprite 打包在同一张图片上。所以,我希望框架可以帮我在运行时打包 sprite 。即,每帧要渲染的 sprite 自动装箱在一张大的 GPU 贴图上。长时间不绘制的 sprite 则避免加载到显存(如果整个游戏的 sprite 很多,需要分关卡加载)。
在 soluna 中,我采用了这样的思路:
游戏初始化时,设定最大使用的 sprite 总数量。这样方便初始化一个数组存放相关元信息。
这个 C 结构并不大(16 字节),所以即使把总设定为 100 万(通常用不了这么多),也只需要 16M 内存,并不过分。
初始的贴图 texid 为 0 ,表示这个 sprite 不存在任何贴图上。另外,这个信息中有一个 frame ,它用来记录这项
sprite_rect数据最后一次在哪一帧使用过。在渲染环节,当这个sprite_rect数组中存在 texid 为 0 ,且 frame 为当前帧时,会把它们装在已存在的贴图组的最后一张贴图上。如果最后这张贴图装不下,再新构造一张贴图。程序定期检查数组中的 sprite 的访问情况,当有一定比例的 sprite 很长时间没有使用过,就复制整个数组,并将复制品中全部的 texid 置为 0,并把最近使用过的那部分 sprite 的 frame 置为当前 frame 。然后在这个复制品上额外做一次装箱(放在独立线程中)。这个装箱的结果产生后,再合并回原始数组。
这个重排的步骤并不会阻塞主线程,但它可以优化 GPU 上的贴图。
这种运行时动态装箱的方法,在显存使用效率上可能比预处理的贴图装箱方法要低,但是浪费并不会太多。它应该给快速迭代开发带来的收益更大。也更适合游戏开发 mod 供玩家扩展。
如有必要,还可以额外写一个预装箱的模块。
soluna 是多线程(通过 ltask 的多服务实现)结构。渲染层通过 sokol 的图形 api 实现渲染。sokol api 本身并不支持多线程,所以所有图形指令都必须放在同一个服务中。这个被称为 render 服务。
render 服务支持多个绘图指令的 batch ,batch 默认为 sprite 的绘制队列。其它业务服务向 render 注册 batch 。一旦 batch 注册后,每个渲染帧都必须完成所有已注册的 batch 才会结束这一帧。
所谓注册,就是向 render 服务申请一个 batch id ,实际数据是通过 batch 的 C 结构完成的。每个 batch id 不一定对应同一个 batch 结构,这样,业务线程可以给每个 batch 构造两个结构,轮替使用。这是一个双缓存设计,每次提交一组数据给渲染线程,然后自己用另一个 batch 结构装载下一帧的数据。
Beta Was this translation helpful? Give feedback.
All reactions