User Tools

Site Tools


zh_cn:tutorial:colorprovider

颜色提供器

有没有想过,草和树叶如何根据生物群系(biome)而改变色调,或者皮革盔甲如何具有看似无限的颜色模式?答案是颜色提供器,这个可以允许你根据位置、NBT、方块状态等属性为方块或物品的模型纹理设置色调或者着色。

现有例子

首先,现有的哪些原版内容使用颜色提供器?一些示例包括:

  • 树叶
  • 皮革盔甲着色
  • 红石线
  • 西瓜、甘蔗和睡莲等植物
  • 药箭

颜色提供器功能强大,但是Mojang选择对混凝土、羊毛和玻璃等有色方块坚持使用单独的纹理。此时的主要用例是针对受生物群系的方块,以及对现有纹理的细微调整,例如药箭的彩色末端。

颜色提供器背后的概念很简单。你为之注册方块和物品,并在渲染该方块或物品的模型时,颜色提供器对纹理的每一层应用色调调整。两个提供器都可以访问模型的层,这意味着您可以分别对模型的每个部分进行色调设置,皮革盔甲和药箭就是这种情况。当您只想更改几个像素而不是整个纹理时,这很有用。

请记住,颜色提供器是客户端机制。确保将与其相关的所有代码放入客户端初始化器中。

注册方块颜色提供器

要将方块注册到方块颜色提供器,您需要使用 Fabric 的 ColorProviderRegistry。此类中有一个BLOCK和ITEM提供器的实例,可以其调用 register。register 方法接受您的颜色提供程序的一个实例,以及您要使用该提供程序进行着色的每个方块的变量。

ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> 0x3495eb, MY_BLOCK);

我们在这里所做的只是说:“Hi,MY_BLOCK 应被着色为 0x3495eb”,也就是蓝色。你有 BlockState、World 和 BlockPos 的环境,基于这些环境的生物群系或者位置等来改变颜色。最终的 int 是 tintIndex,每个都会单独为颜色获取一个,但是在此例中,我们只返回蓝色。

如果你需要在颜色提供器中访问 BlockEntity 数据,你需要实现 RenderAttachmentBlockEntity 以返回你需要的数据。这是因为方块可以在单独的线程渲染,所以直接访问数据并不安全。而且,如果使用 getBlockState 查询方块,你无法查看整个世界——确保你只查询当前位置的 ±2 方块范围内的位置。

模型也重要的:这里需要注意的是,你一定要为模型的每一个你需要着色的部分定义tintindex。如要查看这个的例子,请参考 leaves.json,这是原版树叶使用的基本模型。这里是我们方块使用的模型:

{
  "parent": "block/block",
  "textures": {
    "all": "block/white_concrete",
    "particle": "#all"
  },
  "elements": [
    { "from": [ 0, 0, 0 ],
      "to": [ 16, 16, 16 ],
      "faces": {
        "down":  { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "down" },
        "up":    { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "up" },
        "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "north" },
        "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "south" },
        "west":  { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "west" },
        "east":  { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "east" }
      }
    }
  ]
}

在这种情况下,我们添加了一个单一的 tintindex,出现在 tintIndex 参数中(着色索引0)。

这是最终结果——请注意,原始模型使用了 white_concrete(白色混凝土)纹理(下图使用了 imgur 图床):

注册物品颜色提供器

物品是类似的,区别在于提供的上下文。不访问状态、世界和位置,而是访问 ItemStack

ColorProviderRegistry.ITEM.register((itemStack, layer) -> {
	return 0x3495eb;
}, COLORED_ITEM);

这会以像方块那样的方法为你物品栏中的物品提供色相。

限制

使用颜色提供器的一个关键问题是物品的提供器中缺少上下文。这就是为什么原版草不会根据您站立的位置改变物品栏中的颜色的原因。为了实现诸如方块的颜色变体(混凝土、玻璃、羊毛等)之类的东西,建议您为每个版本简单地提供单独的纹理。

zh_cn/tutorial/colorprovider.txt · Last modified: 2023/11/18 08:37 by solidblock