渲染特征

渲染特征

渲染特征(feature)表示未烘焙进世界几何体的一组对象,例如实体、文本和粒子。这些对象通常具有动态位置,因此下落中或手持的方块与物品也属于此类。特征渲染器的作用是更好地批处理并排列最终绘制到屏幕上的对象。它分为提交阶段和渲染阶段:前者收集所有特征,后者渲染已收集的特征。

提交特征

特征提交通常由负责相应对象的底层子系统处理:实体由 EntityRenderer 处理,方块实体由 BlockEntityRenderer 处理,粒子由 ParticleGroupRenderState 处理,等等。各子系统都提供自己的 submit 方法,通常接收对象的一般渲染状态。随后通过 SubmitNodeCollector 提交必要元素,将其存入 SubmitNodeCollection 树映射以供渲染。

收集器提供以下方法,表中顺序也是最终的渲染顺序:

方法 描述
submitShadow 按指定半径、位置和不透明度绘制若干黑色椭圆。
submitNameTag 按透明度排序的文本。
submitText 文本。
submitFlame 应用于实体的火焰覆盖层。
submitLeash 由 24 段组成的平面。
submitModel 带有渲染状态、按透明度排序的 Model。
submitModelPart ModelPart。
submitMovingBlock 带动态光照的 BlockStateModelPart 列表。
submitBlockModel 带烘焙光照的 BlockStateModel。
submitBreakingBlockModel BlockStateModel 上方的破坏裂纹覆盖层。
submitItem 已拆解的 ItemStackRenderState。
submitCustomGeometry 自定义方法,定义上传到指定 RenderType 缓冲区的顶点。
submitParticleGroup 用于缓存并写入一批粒子四边形的渲染器。

NeoForge 还添加了 submitMultiLayerBlockModel,用于提交 BlockStateModelPart 列表,并完整支持每个四边形使用不同渲染类型,而不是将全部四边形放入单一类型层。

警告 调用方法之后,应将提交给收集器的各元素视为不可变对象。PoseStack 等某些元素会在提交时建立快照,防止后续修改影响它们。

从技术上讲,上述所有方法都属于父接口 OrderedSubmitNodeCollector。这是因为收集器可以按“顺序值”(order)对特征分组,每组代表渲染器的一次处理。默认情况下,所有特征都在顺序值 0 中渲染,按照下述渲染顺序绘制。顺序值较小的组先渲染,较大的组后渲染。可以使用 SubmitNodeCollector#order 指定元素的绘制顺序值:

// Assume we have some SubmitNodeCollector collector

// This will be rendered on order 0.
collector.submitModel(...);

// This will be rendered before the model.
collector.order(-1).submitBlockModel(...);

// This will be rendered after the model.
collector.order(1).submitParticleGroup(...);

渲染特征

特征渲染通过 FeatureRenderDispatcher 的 renderAllFeatures 完成,渲染 SubmitNodeStorage 中提交的对象;该存储持有 SubmitNodeCollection 树映射。分发器包含一组渲染器类,分别负责渲染特定类型的已提交对象。整个顺序分为两个阶段:不透明特征渲染和透明几何体渲染。

对于不透明特征,在某个给定顺序值内,按以下顺序渲染:

  • 模型
  • 模型部件
  • 实体火焰覆盖层
  • 拴绳
  • 物品
  • 移动中的方块
  • 方块模型
  • NeoForge 的多层方块模型
  • 自定义几何体
  • 粒子

对于透明特征,在某个给定顺序值内,按以下顺序渲染:

  • 阴影
  • 模型
  • 模型部件
  • 名称标签
  • 文本
  • 物品
  • 移动中的方块
  • 方块模型
  • NeoForge 的多层方块模型
  • 自定义几何体

透明粒子会在所有透明特征完成后,作为单独一次处理进行渲染。

特征渲染完成后,会清空 SubmitNodeStorage 供下次使用。每帧可能多次调用特征渲染器,因为它除了渲染世界,也用于手持物品和画中画 GUI 渲染器。在这些情况下,renderAllFeatures 之后还会调用 MultiBufferSource.BufferSource#endBatch,构建网格并将其绘制到缓冲区。


来源: NeoForged/Documentation(26.1)。中文翻译依据提交 4a680cdd4d15。