模型
模型是决定方块或物品外观形状及纹理的 JSON 文件。模型由多个尺寸各异的长方体元素构成,每个面都可指定纹理。
物品使用客户端物品中定义的模型,方块使用方块状态文件中关联的模型。模型位置相对于 models 目录,例如 examplemod:item/example_model 对应 assets/examplemod/models/item/example_model.json。
格式规范
另见 Minecraft Wiki 的模型页面。
模型 JSON 根对象支持以下可选属性:
loader:NeoForge 新增,指定自定义模型加载器,详见模型加载器。parent:以相对于models文件夹的资源位置指定父模型。先应用父模型的全部属性,再由当前模型中指定的属性覆盖。常见父模型有:minecraft:block/block:所有方块模型的通用父模型。minecraft:block/cube:所有使用 1×1×1 立方体的模型的父模型。minecraft:block/cube_all:六面使用相同纹理的立方体变体,例如圆石、木板。minecraft:block/cube_bottom_top:四个水平侧面共用纹理,顶面和底面各有单独纹理,例如砂岩、錾制石英块。minecraft:block/cube_column:有侧面纹理和上下端纹理的立方体变体,例如原木、石英柱、紫珀柱。minecraft:block/cross:两个平面使用同一纹理,分别顺时针和逆时针旋转 45°,从上方看形成 X。多数植物使用它,例如草、树苗和花。minecraft:item/generated:传统二维平面物品模型的父模型,游戏中多数物品使用它。由于四边形由纹理生成,elements段会被忽略。minecraft:item/handheld:适合玩家手持显示的二维物品模型,主要用于工具。它继承item/generated,因此也忽略elements。- 方块物品经常直接使用对应的方块模型作为物品模型,但并非总是如此。例如圆石客户端物品使用
minecraft:block/cobblestone。
ambientocclusion:是否启用环境光遮蔽,仅对方块模型生效,默认true。自定义方块模型出现奇怪阴影时,可尝试设为false。gui_light:取"front"或"side"。前者让光从正面照射,适合二维平面;后者从侧面照射,适合三维模型,尤其是方块模型。默认"side",只对物品模型生效。textures:将名称(材质变量)映射到Material的子对象。材质变量可在元素中引用,也可以先在元素中引用而不在当前模型定义,由子模型提供。sprite:纹理位置。force_translucent:为true时,强制将使用此纹理的面放入 translucent 半透明层。为false时:- 若所有像素均不透明(alpha 为
255),使用 solid 层。 - 若像素只有完全不透明或完全透明(alpha 为
0或255),使用 cutout 层。 - 其他情况使用 translucent 层。
- 若所有像素均不透明(alpha 为
建议 方块模型还应指定
particle纹理,用于落到方块上、在上面奔跑或破坏方块时的粒子。物品模型还可使用
layer0、layer1等分层纹理,较高序号绘制在较低序号上方,例如layer1在layer0上方。仅当父模型为item/generated时有效,且最多支持五层,即layer0至layer4。
elements:长方体元素列表。display:保存不同显示视角选项的子对象,具体键见链接页面。仅影响物品模型,但经常定义在方块模型中供物品继承。各视角都是可选子对象,含以下选项,并按此顺序应用:translation:平移,以[x, y, z]表示。rotation:旋转,以[x, y, z]表示。scale:缩放,以[x, y, z]表示。right_rotation:NeoForge 新增,缩放后再应用的第二次旋转,以[x, y, z]表示。
transform:见根变换。
建议 不确定某项该如何设置时,可以查看实现类似效果的原版模型。
元素
元素是长方体的 JSON 表示,支持以下属性:
from:起始角坐标,格式[x, y, z],单位为 1/16 方块。例如[0, 0, 0]表示“左下”角,[8, 8, 8]是中心,[16, 16, 16]是“右上”角。to:结束角坐标,格式及单位同from。
建议 Minecraft 将
from和to限制在[-16, 32]范围内,但强烈不建议超出[0, 16],否则可能出现光照或剔除问题。
neoforge_data:见额外面数据。faces:最多六个面的数据,名称分别是north、south、east、west、up和down。每个面包含:
此外,还可指定以下可选属性:
shade:仅用于方块模型,决定元素各面是否使用依赖方向的明暗效果,默认 true。rotation:元素旋转,子对象包含:angle:旋转角度,单位为度。axis:旋转轴,目前不能同时绕多个轴旋转。origin:可选,旋转中心,格式[x, y, z],是绝对坐标而不是相对于长方体的位置,省略时为[0, 0, 0]。
额外面数据
neoforge_data 可以应用于整个元素或单独的面,在所有位置都可省略。同时存在元素级与面级设置时,面级设置覆盖元素级。支持:
color:用 ARGB 颜色给面着色,可为字符串或十进制整数,JSON 不支持十六进制字面量。默认0xFFFFFFFF。颜色不变时,可以用它代替动态着色。block_light:覆盖该面的方块光照,默认 0。sky_light:覆盖该面的天空光照,默认 0。ambient_occlusion:启用或禁用该面的环境光遮蔽,默认沿用模型设置。
根变换
在模型顶层添加 NeoForge 提供的 transform 属性,会在应用方块状态文件中的旋转(方块模型)或 display 中的变换(物品模型)之前,对全部几何体应用变换。
根变换有两种指定方式。第一种是在 matrix 属性中放入嵌套 JSON 数组表示的 3×4 变换矩阵,使用行主序,省略最后一行。该矩阵依次组合平移、左旋转、缩放、右旋转及变换原点。示例如下:
{
// ...
"transform": {
"matrix": [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
}
}
第二种是用 JSON 对象任意组合以下条目,并按此顺序应用:
translation:相对平移,三维向量[x, y, z],默认[0, 0, 0]。rotation或left_rotation:缩放之前、绕平移后的原点旋转,默认不旋转,可用以下形式:- 单个轴到角度的映射,例如
{"x": 90}。 - 一组单轴映射,按列出顺序应用,例如
[{"x": 90}, {"y": 45}, {"x": -22.5}]。 - 三个值分别表示绕各轴旋转,例如
[90, 45, -22.5]。 - 四个值直接表示四元数,例如
[0.38268346, 0, 0, 0.9238795],表示绕 X 轴 45 度。
- 单个轴到角度的映射,例如
scale:相对于平移后原点的缩放,格式[x, y, z],默认[1, 1, 1]。post_rotation或right_rotation:缩放后绕平移后的原点旋转,默认不旋转,格式与rotation相同。origin:旋转和缩放的原点,变换最后也会移动到这里。可以使用三维向量[x, y, z],或内置值"corner"([0, 0, 0])、"center"([0.5, 0.5, 0.5])、"opposing-corner"([1, 1, 1],默认)。
方块状态文件
另见 Minecraft Wiki 的方块状态文件页面。
游戏通过方块状态文件为不同方块状态分配模型。每个已注册方块必须恰好有一个文件。指定模型有三种互斥方式:variants、multipart,以及 NeoForge 添加的定义类型。
variants 段为每种状态提供一个条目,是最常见的关联方式,绝大多数方块使用它。
- 键为不含方块名的状态字符串。例如,不含水的上半台阶使用
"type=top,waterlogged=false",无属性方块使用""。未参与模型选择的属性可以省略:若waterlogged不影响模型,type=top,waterlogged=false和type=top,waterlogged=true可合并为一个type=top条目。因此空字符串对任意方块也都是有效键。 - 值是单个模型对象或模型对象数组。数组会随机选择一个模型。模型对象包含:
type:NeoForge 新增,设置自定义方块状态模型加载器,详见对应文档。model:相对于命名空间models文件夹的模型路径,例如minecraft:block/cobblestone。x和y:绕对应轴的旋转,只能以 90 度为步长,均可省略,默认 0。uvlock:旋转时是否锁定 UV,可选,默认 false。weight:仅对数组有效,随机选择时的权重,可选,默认 1。
multipart 则根据状态属性组合多个元素,主要用于栅栏和墙,根据布尔属性启用四个方向的部分。每个元素由 when 和 apply 两段组成。
when指定状态的字符串表示,或需要满足的属性列表。列表可命名为"OR"或"AND",对内容执行对应逻辑运算。单状态或列表中的属性都可以用|分隔多个实际取值,例如facing=east|facing=west。apply指定使用的模型对象或模型对象数组,工作方式与variants完全相同。
最后,还可通过 neoforge:definition_type 指定用于注册方块状态文件的自定义加载器,见方块状态定义加载器。
客户端物品
游戏通过客户端物品,为 ItemStack 的不同状态指定一个或多个模型。虽然模型 JSON 仍有物品专用字段,但客户端物品会根据上下文选择模型,因此多数信息已移到独立章节。
着色
草、树叶等方块会根据位置或属性改变纹理颜色。模型元素可在面上指定着色索引,由颜色处理器处理。代码提供三个事件,分别用于方块着色来源、基于生物群系的方块颜色(配合来源使用),以及物品着色来源。先看方块着色来源:
@SubscribeEvent // on the mod event bus only on the physical client
public static void registerBlockColorHandlers(RegisterColorHandlersEvent.BlockTintSources event) {
// Parameters are the block's state, the level the block is in, the block's position, and the tint index.
// The level and position may be null.
event.register(
// A list of tint sources to apply to the block. The 'tintindex' defined in
// the model indexes into the list.
List.of(
// For 'tintindex: 0'.
// Takes in the block's state.
state -> {
// Replace with your own calculation. See the BlockColors class for vanilla references.
// Colors are in ARGB format.
return 0xFFFFFFFF;
},
// For 'tintindex: 1',
new BlockTintSource() {
@Override
public int color(BlockState state) {
// The default tint to apply.
return 0xFFFFFFFF;
}
@Override
public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) {
// The tint to apply when the block is in the world.
// Defaults to `color` if not overridden.
return 0xFFFFFFFF;
}
@Override
public int colorAsTerrainParticle(BlockState state, BlockAndTintGetter level, BlockPos pos) {
// The tint to apply when a `TerrainParticle` is spawned.
// Defaults to `colorInWorld` if not overridden.
return 0xFFFFFFFF;
}
}
),
// A varargs of blocks to apply the tinting to
EXAMPLE_BLOCK.get(), ...
);
}
下面是颜色解析器的示例:
@SubscribeEvent // on the mod event bus only on the physical client
public static void registerColorResolvers(RegisterColorHandlersEvent.ColorResolvers event) {
// Parameters are the current biome, the block's X position, and the block's Z position.
event.register((biome, x, z) -> {
// Replace with your own calculation. See the BiomeColors class for vanilla references.
// Colors are in ARGB format.
return 0xFFFFFFFF;
});
}
物品着色见客户端物品文档的相关小节。
注册独立模型
没有以任何方式关联方块或物品、但其他上下文仍需使用的模型,例如方块实体渲染器中的模型,可通过 ModelEvent.RegisterStandalone 注册:
// This can be any type as long as it can be obtained from the ResolvedModel and the ModelBaker
// The generic type should be whatever is the generic type of the UnbakedStandaloneModel<T>
public static final StandaloneModelKey<QuadCollection> EXAMPLE_KEY = new StandaloneModelKey<>(
new ModelDebugName() {
@Override
public String debugName() {
// A name for the standalone model
// Can be any string, but it should contain the mod id
return "examplemod: Example Model";
}
}
);
@SubscribeEvent // on the mod event bus only on the physical client
public static void registerAdditional(ModelEvent.RegisterStandalone event) {
event.register(
// The model to get
EXAMPLE_KEY,
// An UnbakedStandaloneModel<T> we care about, in this case one that returns a QuadCollection
// Can use the static methods from SimpleUnbakedStandaloneModel<T> for simplicity
SimpleUnbakedStandaloneModel.quadCollection(
// The model id, relative to `assets/<namespace>/models/<path>.json`
Identifier.fromNamespaceAndPath("examplemod", "block/example_unused_model")
)
);
}
来源: NeoForged/Documentation(26.1)。中文翻译依据提交
4a680cdd4d15。