Lucis

Lucis

一个轻量级的服务器端光照引擎,能大幅加速任何与光照相关的任务,速度提升可达约8-12倍!

性能

Lucis

Lucis 是一个轻量级的服务端光照引擎。它用更快的基于区域(region)的系统替代了原版 Minecraft 光照管线中开销较大的部分,该系统专为高更新吞吐量、更快的区块光照以及更好的多核 CPU 扩展性而设计,从而能够在不造成严重 TPS 下降的情况下,加快世界生成和大型结构生成的加载速度。

起初,这只是一个为了解 Minecraft 光照引擎工作原理而开展的研究项目,但最终因为原版光照引擎对我来说处理速度太慢,我便着手重写了光照系统,并决定尝试用它来创造一些乐趣,这便有了这个项目!

我想在世界中生成巨大(真的是非常巨大!)的结构,但发现原版的光照引擎面对这种情况时…… 你知道,它没预料到需要光照计算影响如此之多的方块,导致自身陷入卡顿,所以我试图解决这个问题。

是的,确实已经有 Starlight 和 ScalableLux 这样的模组存在。但我更想自己去研究和探索,而不是直接使用现成的解决方案。所以,这就是 Lucis,它将光照速度提升了约 8-12 倍(相比原版),并且比 ScalableLux/Starlight 快约 1.5 倍!

Lucis 做了什么?

Lucis 优化了世界生成过程中区块准备阶段以及运行时方块变化后的方块光和天空光更新。

Lucis 并不完全依赖原版逐次更新的光照行为,而是将光照变化按区域分组,尽可能异步处理,然后分批将计算出的光照数据发布回 Minecraft 的光照引擎。

目标非常简单:减少高强度方块更新、区块加载和天空光变化期间的光照计算成本。

它是如何工作的?

这是 Starlight 的另一个分支吗?

不,这是另一种尽可能优化光照计算的方法。让我尝试描述一下。

Minecraft 按区块(section)存储光照,并在方块被放置、移除、生成或改变时更新光照。虽然这对于常规游戏玩法来说运行良好,但当游戏需要在短时间内处理大量影响光照的方块或生成世界时,可能会变得缓慢。

Lucis 通过将光照工作收集到区域中来改变这一点。区域是一小片拥有所有权的区块范围,可以作为一个整体单元进行处理。当发生方块更新时,Lucis 会记录该变化,将其与附近的变化分组,并将该工作发送到其运行时光照系统。这避免了将每次小的更新都视为完全独立的光照操作。

对于区块光照,Lucis 可以使用自己重新光照路径在世界生成期间计算光照。它读取区块及其附近的光照数据,计算天空光和方块光,然后将完成的光照区块数据发布回 Minecraft 的光照线程。

对于运行时方块变化,Lucis 使用自己的光照队列。如果在同一 tick 内或相邻位置有许多方块发生变化,该队列允许 Lucis 将它们作为分组的区域任务进行处理。这对于密集的方块更新、地形编辑、生成的结构以及由屋顶或大开口引起的天空光变化尤其有用。

Lucis 还将计算与发布分离。繁重的工作可以在主光照更新路径之外完成,因此最终的光照区块数据可以分批发布回去。这减少了必须逐一通过光照线程的小型光照任务数量。结果是当许多光照变化同时发生时,开销更低。

主要的技术难点在于,我们仍然需要尊重 Minecraft 的区块状态和光照引擎规则,以避免破坏许多其他可能获取光照数据或实现自身系统的模组。Lucis 计算新的光照数据,跟踪变化的区域,然后将结果交还给引擎。

基准测试

第一次基准测试在 Minecraft 1.21.1 和 NeoForge 21.1.234 上运行,使用相同的基准测试环境(如种子、坐标和环境)比较了 Vanilla、ScalableLux 和 Lucis。加载了 3 个区块半径内的出生点,总共计算了 36 个区块。

测试平台:AMD Ryzen 3700x,为 Lucis 分配了 4 个线程。

ScalableLux 0.1.0.1+neoforge.1cb1e91 使用默认配置,配置文件中的 parallelism=-1。

ns/change 数值越低越好。

工作负载 Vanilla ns/change ScalableLux ns/change Lucis ns/change Lucis vs Vanilla Lucis vs ScalableLux
block_toggle_border 322846.1 43999.7 28881.8 11.18x 1.52x
dense_chunk_patch 17766.0 3480.5 3002.3 5.92x 1.16x
edge_toggle 80824.9 26701.6 18182.0 4.45x 1.47x
roof_toggle 22076.0 4680.8 2441.8 9.04x 1.92x
sky_hole 213509.0 119023.0 114414.0 1.87x 1.04x

第二次基准测试在 Minecraft 26.2 和 NeoForge 26.2.0.1-beta 上运行,使用相同的基准测试环境(如种子、坐标和环境)比较了 Vanilla、ScalableLux 和 Lucis。加载了 3 个区块半径内的出生点,总共计算了 36 个区块。

测试平台:AMD Ryzen 3700x,为 Lucis 分配了 4 个线程。

ScalableLux 0.3.0-alpha.0.16+26.2 使用默认配置,配置文件中的 parallelism=-1。

ns/change 数值越低越好。

工作负载 Vanilla ns/change ScalableLux ns/change Lucis ns/change Lucis vs Vanilla Lucis vs ScalableLux
block_toggle_border 208909.3 165328.8 20695.4 10.09x 7.99x
dense_chunk_patch 10319.5 3608.4 2221.0 4.65x 1.62x
edge_toggle 26914.0 31825.3 21074.7 1.28x 1.51x
roof_toggle 15469.0 8405.7 2398.7 6.45x 3.50x
sky_hole 110073.3 112749.3 85347.3 1.29x 1.32x

兼容性

尽管 Lucis 尽可能尝试与其他模组保持兼容性,并且通常不会破坏任何东西,但最终仍可能出现问题。在大型整合包中使用时请务必小心。

已知说明:

  • ScalableLux(或任何 Starlight 分支)从定义上就是不兼容的。你只能选择 Lucis 或只能选择 ScalableLux,不能同时使用。试图同时放入两者会导致大量崩溃。请不要尝试将两者都放入你的整合包中,谢谢。那样是行不通的。
  • Sable 与 Lucis 兼容。目前 Lucis 不会为 Sable 的领地注入其光照,因此这些领地目前使用原版光照进行投影。一旦找到更好的解决方案,未来可能会改变。
  • 与大多数世界生成优化模组应该基本兼容,例如 Generator Accelerator、C2ME、Fast Noise 和 ModernFix(我想某些补丁仍然有效)。Lucis 在不同场景下可将世界生成速度提升约 +15-25%。不错吧?

如果某个模组也替换或大幅修改了 Minecraft 光照内部机制,那么它很可能与 Lucis 冲突。

整合包

只要遵守 LGPLv3 许可条款,你可以在个人和公共整合包中使用它,包括分发整合包。