## 1️⃣ `VertexFormat` 的作用 在 Minecraft 渲染系统中,`VertexFormat` 是**顶点格式的描述类**。它定义了: * 每个顶点包含哪些属性(position、color、normal、uv 等) * 每个属性的数据类型和大小 * 这些属性在 GPU 缓冲区中的排列顺序(stride 和 offset) 换句话说,它告诉 GPU **如何从 VBO 里正确读取顶点数据**。 Minecraft 不再直接使用 `glVertex3f` 或 `glColor4f`,而是通过 `VertexFormat` + `BufferBuilder` 构建顶点数组,然后一次性上传到 GPU。 --- ## 2️⃣ `VertexFormat` 的核心结构 在 Minecraft 中,`VertexFormat` 类主要包含: | 成员 | 含义 | | ------------ | ---------------------------------- | | `elements` | 顶点属性列表,每个元素是 `VertexFormatElement` | | `vertexSize` | 每个顶点的总字节数(stride) | | `hasColor` | 是否包含颜色属性 | | `hasNormal` | 是否包含法线 | | `hasUV` | 是否包含纹理坐标 | ### `VertexFormatElement` 每个元素描述一个顶点属性,包含: | 属性 | 含义 | | ------- | -------------------------------------- | | `type` | 数据类型(FLOAT、UBYTE 等) | | `usage` | 属性用途(POSITION、COLOR、UV、NORMAL、PADDING) | | `count` | 该属性的分量个数(例如 POSITION = 3, COLOR = 4) | | `index` | 纹理坐标索引(有多个 UV 时用) | **示例:** Minecraft 默认块渲染顶点格式可能包含: ```text POSITION (3 floats) COLOR (4 bytes) UV0 (2 floats) NORMAL (3 bytes) UV1 (2 floats, 光照贴图) ``` --- ## 3️⃣ `VertexFormat` 在渲染管线中的位置 1. **顶点构建** ```java BufferBuilder buffer = Tesselator.getInstance().getBuilder(); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); buffer.vertex(x, y, z).color(r, g, b, a).uv(u, v).normal(nx, ny, nz).endVertex(); ``` 2. **上传 GPU** * `BufferBuilder` 会根据 `VertexFormat` 的定义把每个顶点的数据打包成连续的 **VBO 字节流** * 使用 `glVertexAttribPointer` 告诉 GPU 每个属性的偏移量和类型 3. **绑定着色器** * 着色器使用 `layout(location = X)` 对应 VertexFormat 的属性 * GPU 就能正确读取每个顶点属性用于渲染 --- ## 4️⃣ 常用顶点格式示例 Minecraft 1.20.1 内置了几种常用格式: | 名称 | 用途 | | ----------------------------------------------- | ----------------------------------------- | | `DefaultVertexFormat.POSITION_COLOR` | GUI、简单方块渲染 | | `DefaultVertexFormat.BLOCK` | 方块渲染,包含 position/color/uv/normal/lightmap | | `DefaultVertexFormat.ITEM` | 物品渲染,类似 BLOCK | | `DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL` | 高级渲染,需要所有属性 | --- ## 5️⃣ 总结 * `VertexFormat` 是 **顶点数据布局描述器**,告诉 GPU 每个顶点包含哪些属性、类型和顺序。 * Minecraft 的现代渲染完全基于 **VBO + VAO + 着色器**,`VertexFormat` 作为桥梁,让 Java 层构建的顶点数据正确映射到 GPU。 * 对于 mod 开发或自定义渲染,理解 VertexFormat 非常关键,因为你需要确保 **BufferBuilder 构建的数据格式和着色器匹配**。