跳到主要内容

设置与性能


设置

在Forge版本的游戏中默认按下Alt+M,你就能打开MadParticle Designer GUI,找到设置界面。

以下提到的所有设置项,在必要的情况下,都可以在.minecraft/config/MadParticleConfig.json中手动更改。

通用

最大粒子数量

滑块的数值范围是8192~1000000。

在原版设定下,每种RenderType各自的粒子数量最大为16384,而我们通常只使用有限的一两种RenderType,在这种情况下使得世界内粒子最大数量相当于16384。MadParticle允许你自由调整此值。

信息

MadParticle的最初设计应用是线上多人展会或类似场景,由于各个玩家硬件状况不同,在这种情况下:

  • 如果粒子指定的渲染类型实例化,我们建议将场景粒子总数控制在100000以内;
  • 如果粒子指定的渲染类型是半透明不透明,我们建议将场景粒子总数控制在8000以内。

始终限制最大生成距离

当粒子生成时,其与摄像机的距离将有两道阈值:

  1. 一般最大生成距离:视距的一半,只有始终渲染true的粒子可以在这个距离外生成;
  2. 强制最大生成距离:视距的两倍,即使是始终渲染为true的粒子也不能在此距离外生成。将始终限制最大生成距离设置为可以取消掉此限制。

辅助线程数

信息

循环按钮的排列顺序为仅主线程(值为1)、648122。默认值为4。如需要未提供的其他值,请直接修改配置文件。

指定有多少辅助线程将被用于辅助计算,通常推荐这个值略小于或等于你的CPU核心数量。

  • 大于核心数时辅助线程之间会产生竞争,从而使得效率降低;
  • 等于核心数时,
    • 后台的其他程序可能会与Minecraft产生竞争,影响后台程序运行;
    • Minecraft切换到主线程所花的时间可能会更久,使游戏帧数产生明显波动,故只推荐用在追求最高效率的固定场景;
信息

上文提到的“CPU核心数量”不考虑超线程技术,仅指物理核心。

对于混合架构用户,目前MadParticle还做不到区分大小核并智能分配任务,您可能需要手动指定Minecraft仅在大核上运行。在这种情况下,你可以将辅助线程数指定等于您的大核(P-core)数量。

提示

服务端解析/mp指令所使用的多线程不受此限制。

半透明处理方式

半透明面作为图形学经典问题,MadParticle允许你选择你想要的半透明处理方式。

  • 深度测试:启用:原版方法。不同深度的重叠粒子只会有一个或几个被渲染,适用于不透明粒子占多数的场景。
  • 深度测试:禁用:不同深度的重叠粒子被直接叠加在一起,而不考虑其具体的深度大小。适用于同种半透明粒子占多数的场景。
  • 加权混合OIT:顺序无关半透明(Order Independent Transparency)的简单加权方式实现,通过特定公式由透明度和深度计算出权重再进行叠加,可以实现较为正确的半透明渲染。普遍适用于多种场景,但性能消耗比前两者稍大。
信息

深度:想象从摄像机中向前射出一条线,这条线依次由近及远穿过了多个半透明面,这些面具有不同的“深度”。


附加

接管粒子渲染

循环按钮为不接管仅原版原版及其他Mod。默认为仅原版

  • 设为仅原版时,MadParticle会把大部分原版粒子的渲染方式修改为实例化,从而极大地提升性能;
  • 设为原版及其他Mod时,MadParticle会把所有渲染类型为半透明不透明的粒子修改为实例化。这会使得一些具有特殊渲染的粒子不再遵循其自身的渲染逻辑,因此一般不建议使用。

接管粒子计算

循环按钮为不接管仅原版原版及其他Mod。默认为原版及其他Mod

  • 设为不接管时,粒子计算(tick)将按原版逻辑在主线程中执行(包括MadParticle粒子);
  • 设为仅原版时,全部原版(除非我找漏了)粒子和MadParticle粒子的计算将会并行化,从而提升性能。由于需要额外过滤其他Mod粒子,性能会略低于原版及其他Mod模式;
  • 设为原版及其他Mod时,全部粒子计算将会并行化,按辅助线程数分摊任务。通常情况下不需要额外关心,如果有其他Mod粒子产生错误从而需要特别地将其调回主线程,你可以手动选择仅原版

改进命令方块编辑界面

拉长命令方块的输入框,并在其下方增加一个直接跳转至Designer GUI的按钮。

粒子计数器

在左上角显示一个简易的临时计数器。和完整的F3相比可以节省性能。


光照缓存

在以摄像机为中心的一个柱形范围内,方块坐标的光照值会被以最快速的方式缓存,但这种方式会消耗一定的内存。

水平范围、垂直范围

指定如上所述柱形的大小。

强制光照为15

跳过所有光照计算,直接将光照强制设置为15(最亮)。可以取得最好的性能。

刷新间隔

缓存刷新间隔越短,消耗的性能也越多。如果摄像机(玩家)往往在高速移动,那就需要更小的刷新间隔以避免出现黑色伪影。


性能:原理

游戏帧率会受硬件性能、运行环境、软件性能、设置选择、实际场景等许多方面影响。

1.1 实例化

实例化渲染(Instanced Rendering)使得CPU-GPU通信几乎完全不再是渲染瓶颈,能在有大量重复元素时提高帧率。简单来讲,原版粒子的渲染方式逐个地把粒子的数据发送给GPU,有多少粒子就发多少次;实例化渲染是一次性把所有的粒子的数据都发送给GPU,无论多少粒子都只用发一次。

你可以把粒子命令中的渲染类型设为实例化来启用此技术。

我们也支持把原版粒子或/和其他Mod的粒子渲染类型从半透明不透明的粒子修改为实例化。这会使一些具有特殊渲染方法的粒子不再执行其本身的渲染方法,我们已经对原版粒子做了过滤,但对其他Mod的粒子暂时没什么好办法。如果你能容忍其他Mod的粒子的画面错误那你可以把仅原版改为原版及其他Mod以获得最大效率。

以下是可以进行实例化渲染的粒子列表,不在此列表内的粒子不进行实例化渲染:

(此列表可能不会得到及时更新,故可能与实际实现有偶尔出入。)
SnowflakeParticle,
SpitParticle,
SpellParticle,
HeartParticle,
BubbleParticle,
BubbleColumnUpParticle,
BubblePopParticle,
CampfireSmokeParticle,
PlayerCloudParticle,
SuspendedTownParticle,
CritParticle,
WaterCurrentDownParticle,
DragonBreathParticle,
DripParticle,
DustParticle,
EnchantmentTableParticle,
EndRodParticle,
FallingDustParticle,
WakeParticle,
FlameParticle,
SoulParticle,
SculkChargeParticle,
SculkChargePopParticle,
LargeSmokeParticle,
LavaParticle,
NoteParticle,
ExplodeParticle,
PortalParticle,
WaterDropParticle,
SmokeParticle,
SplashParticle,
TotemParticle,
SquidInkParticle,
SuspendedParticle,
ReversePortalParticle,
WhiteAshParticle,
GlowParticle

1.2 并行填充

既然是一次性发送所有粒子的数据,那自然需要CPU先把这些数据填入缓冲区。在消除CPU-GPU通信瓶颈之后,影响帧率的主要瓶颈就是CPU进行各类运算所花的时间。

很幸运地,我们可以便利地利用所有能用的CPU核心来执行填缓冲区的任务而不需要考虑经典的多线程同步/阻塞问题,这使你在上文中选择的辅助线程数对这项工作可以有几乎线性的影响——两个核心需要原来一半的时间,32个核心就只需要原来1/32的时间。当然,如果你的CPU确实有这么多核心,那内存和CPU-GPU带宽可能会成为新的瓶颈。

2.1 并行计算

除了帧内计算要消耗时间,帧间计算也要消耗许多时间——这里特指粒子的tick计算。

原则上讲,粒子与世界应该是几乎独立的:作为一种最初目的是仅客户端的锦上添花的装饰物,除了需要进行碰撞计算的读取外,不应该对世界造成任何影响。同样地,我们也可以把计算并行化,有几个核心就只需要几分之一的时间。

为了预防有其他Mod的粒子不符合这个原则,我们预留了仅原版选项,使其他Mod的粒子留在主线程里计算。但这样就需要额外的筛选,造成一些性能损失。

以下是可以进行并行计算的原版粒子列表,不在此列表内的粒子不能进行并行计算:

(此列表可能不会得到及时更新,故可能与实际实现有偶尔出入。)
BlockMarker,
TerrainParticle,
DustColorTransitionParticle,
HugeExplosionSeedParticle,
HugeExplosionParticle,
SonicBoomParticle,
FallingDustParticle,
FireworkParticles.OverlayParticle,
SnowflakeParticle,
SpitParticle,
AttackSweepParticle,
VibrationSignalParticle,
ShriekParticle,
SpellParticle,
HeartParticle,
BubbleParticle,
BubbleColumnUpParticle,
BubblePopParticle,
CampfireSmokeParticle,
PlayerCloudParticle,
SuspendedTownParticle,
CritParticle,
WaterCurrentDownParticle,
DragonBreathParticle,
DripParticle,
DustParticle,
EnchantmentTableParticle,
EndRodParticle,
FallingDustParticle,
WakeParticle,
FlameParticle,
SoulParticle,
SculkChargeParticle,
SculkChargePopParticle,
LargeSmokeParticle,
NoteParticle,
ExplodeParticle,
PortalParticle,
WaterDropParticle,
SmokeParticle,
SplashParticle,
TotemParticle,
SquidInkParticle,
SuspendedParticle,
ReversePortalParticle,
WhiteAshParticle,
GlowParticle

2.2 内存压力

如上所述,我们成功地增加了计算密度,减少了计算时间。而这会让计算所需内存和GC的压力急剧增大。通常情况下我们建议尽可能地在启动器中增大内存分配,以减少频繁Full GC造成的卡顿——甚至是来不及GC造成的内存不足崩溃。

信息

对于MadParticle粒子,我们已经在新版本中应用了经过极大优化的运动计算代码,大幅减小了内存压力。

3 无能为力

在应用以上这些技术之后,如果世界中还有其他传统渲染类型的粒子,或者有其他Mod的粒子要在主线程里计算,那我们无能为力,只能等待它们完成。

4 粒子本身

粒子本身的属性设置相互叠加也会改变系统压力:

  • 粒子移动会增加tick时的计算压力;
  • 与方块碰撞会增加tick时的计算,也是内存压力的主要来源之一;
    • 过快的速度也可能会增加碰撞计算所需时间;
  • 与玩家互动会增加tick时的计算压力;
  • 渲染类型决定了粒子的渲染效率,通过实例化可以极大地减轻原本的压力;
  • Shimmer联动泛光会增加额外渲染时压力;
  • 粒子消失时召唤新粒子可能会增加内存压力;
  • 数学表达式会在生成粒子时增加一些计算和内存压力;
  • 预计算粒子会由于生成前的密集计算可能会极大地增加内存压力。

5 最后

此外,Shimmer、Optifine、Sodium等渲染/优化相关的模组也可能对帧数有显著的影响。

总之,在上述诸多因素的影响下,大量粒子场景的性能表现可能会很难有游戏世界空间上、时间上、玩家/设备间的可重复性。同一场景的性能表现可能会在多次测量时有明显差异——但原则性的大方向不受影响。

性能:测试

我们提供并使用以下场景进行性能测试,仅供参考。所有场景均使用一个循环型命令方块,其余统一设置为:

  • Minecraft游戏内设置:

    • 图像品质:高品质
    • 渲染距离:12区块
    • 模拟距离:8区块
    • 云:关
    • 难度:和平
    • 超平坦地形
    • MadParticle辅助线程数:与CPU物理核心数相同
  • 其余场景设置:

    • 操作系统:Windows 11 23H2(或更新)
    • 尽量减少后台程序

以下指令均以50000粒子为例。

信息

以下场景的设置原则是简单地兼顾实际使用场景和测试极限性能,故其表现可能与实际情况有所不同。

无物理场景

MadParticle指令

mp minecraft:totem_of_undying RANDOM 100 TRUE 500 ~ ~15 ~ 10.0 10.0 10.0 0.0 0.0 0.0 0.0 0.0 0.0 FALSE 0 0 0 1 1 0.0 0.0 0 0 0 0 0.0 FALSE 0 0 INSTANCED 0.780 0.170 0.962 0 1.0 1.0 LINEAR 1.00 1.00 LINEAR @a {}

有物理场景

MadParticle指令

mp minecraft:totem_of_undying RANDOM 200 TRUE 250 ~ ~1 ~ 0.0 0.0 0.0 0.0 0.35 0.0 0.15 0.05 0.15 TRUE 2 1 1 0.99 0.99 0.1 0.1 0 0 0 0 0.00001 FALSE 0 0 INSTANCED 3 0.496 0.000 0 1.0 1 INDEX 1.2 0.8 LINEAR @a {"light":"15-14t^2"}

原版优化场景

原版指令

particle minecraft:white_ash ~ ~10 ~ 1 1 1 0 1230 force