纹理着色
许多原版方块和物品会根据所在位置或属性改变纹理颜色,例如草。模型支持在面上指定整数“着色索引”,由 BlockColor 和 ItemColor 处理。原版模型中如何定义索引,参见 Minecraft Wiki。
原创说明图,依据 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, ...);
}