纹理着色

纹理着色

许多原版方块和物品会根据所在位置或属性改变纹理颜色,例如草。模型支持在面上指定整数“着色索引”,由 BlockColor 和 ItemColor 处理。原版模型中如何定义索引,参见 Minecraft Wiki。

纹理着色计算示意:灰色像素 RGB 200,200,200 与颜色乘数 80,200,60 逐通道相乘并除以 255,截断后得到 62,156,47;BlockColor 和 ItemColor 分别为方块与物品注册。

原创说明图,依据 Forge 1.21.x 官方文档 绘制。

BlockColor / ItemColor

两者都是单方法接口。BlockColor 接收 BlockState、可空的 BlockAndTintGetter 和可空的 BlockPos;ItemColor 接收 ItemStack。两者都接收整数 tintIndex,即正在着色的面的着色索引,并返回作为颜色乘数的 int。

该整数按从最高有效字节到最低有效字节依次视为四个无符号字节:alpha、红、绿、蓝。对于着色面的每个像素,每个颜色通道的值为 (int)((float) base * multiplier / 255.0),其中 base 是该通道原值,multiplier 是颜色乘数中对应的字节。方块不使用 alpha 通道。

例如,未着色的草纹理呈白灰色。草的 BlockColor 和 ItemColor 返回的颜色乘数红、蓝分量低,alpha 和绿分量高(至少在温暖生物群系如此),因此相乘后绿色突出,红蓝减弱。

物品继承 builtin/generated 模型时,每层(layer0、layer1 等)的着色索引对应层索引。

创建颜色处理器

BlockColor 需要注册到游戏的 BlockColors 实例。可通过 RegisterColorHandlersEvent$Block 获取,并通过 #register 注册。注意,这不会给方块的 BlockItem 着色;BlockItem 是物品,需要 ItemColor。

@SubscribeEvent
public void registerBlockColors(RegisterColorHandlersEvent.Block event) {
  event.register(myBlockColor, coloredBlock1, coloredBlock2, ...);
}

ItemColor 需要注册到游戏的 ItemColors 实例。可通过 RegisterColorHandlersEvent$Item 获取,并通过 #register 注册。此方法还有接收 Block 的重载,实际上是为 Block#asItem 返回的物品(即方块的 BlockItem)注册颜色处理器。

@SubscribeEvent
public void registerItemColors(RegisterColorHandlersEvent.Item event) {
  event.register(myItemColor, coloredItem1, coloredItem2, ...);
}

原文:Coloring Textures。