获取Minecraft所有物品库存/NEI样式渲染图片的技术问询
可行的Minecraft物品/方块渲染图片提取方案
我之前也折腾过类似的需求,踩过不少和你一样的坑——IBakedModel搞不定TESR方块、GL渲染不知道怎么抓单帧、Jar里的纹理碎得乱七八糟。分享几个亲测有效的思路,覆盖你遇到的所有场景:
1. 离屏帧缓冲(Framebuffer)捕获完整渲染结果
这是最通用的方案,能搞定包括TESR方块在内的所有物品渲染,原理是模拟Minecraft的渲染环境,把单个物品的渲染结果捕获到离屏缓冲区,再导出为图片:
- 步骤拆解:
- 创建一个固定尺寸的离屏
Framebuffer(比如256x256,和NEI的物品图标尺寸一致) - 保存当前GL渲染状态(矩阵、纹理绑定、光照设置等),然后重置为物品渲染的干净环境:关闭光照、设置等轴测视角(和NEI保持一致的3D角度)、禁用深度测试
- 针对不同类型的对象处理渲染:
- 普通物品/方块:获取对应的
IBakedModel,调用ModelRenderer的渲染方法,传入ItemStack和合适的变换矩阵 - TESR方块(箱子、熔炉、发射器等):实例化对应的
TileEntity,设置好NBT数据(比如箱子的物品栏),然后获取对应的TileEntitySpecialRenderer,调用其render方法完成渲染
- 普通物品/方块:获取对应的
- 渲染完成后,从Framebuffer中读取像素数据,用ImageIO之类的工具保存为带Alpha通道的PNG文件
- 恢复之前保存的GL渲染状态,避免影响后续程序运行
- 创建一个固定尺寸的离屏
- 关键注意点:一定要处理GL状态的保存和恢复,不然很容易导致程序崩溃或者渲染异常。
2. 参考开源模组的成熟实现
NEI、JEI这类模组已经完美解决了所有物品渲染的问题,直接参考它们的源码能少走很多弯路:
- JEI的
ItemStackRenderer类是核心,里面封装了处理普通物品、TESR方块、动态模型(比如带NBT的物品)的完整逻辑 - 可以直接抽取JEI中渲染相关的代码片段,或者基于JEI的API来实现批量渲染(如果你是做模组的话)
- 另外,Forge的
RenderingRegistry可以帮你快速判断一个方块是否使用TESR,通过RenderingRegistry.hasTileEntityRenderer()方法就能查询
3. 静态纹理拼接(针对无动态效果的物品)
如果只需要处理普通的、无动态渲染的物品,可以直接从Jar包中提取纹理并拼接:
- 通过
ItemStack获取对应的模型,遍历模型中的TextureAtlasSprite引用,找到对应的纹理文件路径 - 对于多层纹理的物品(比如工具的手柄+头部),按照Minecraft的渲染顺序,把多个纹理叠加绘制到一张画布上
- 注意:这种方法只适用于静态模型的物品,带TESR、动态模型(比如旗帜、带附魔的物品)的对象还是得用渲染捕获的方法
额外提示
- 版本兼容性:不同MC版本的渲染API差异极大,比如1.12用的是旧的GL11渲染,1.18+已经切换到Fabric/Forge的新渲染管线,代码要针对目标版本调整
- 性能优化:批量渲染上千个物品时,要复用Framebuffer和渲染上下文,避免频繁创建销毁资源
- 透明通道:Minecraft的物品渲染有大量透明/半透明部分,保存图片时一定要保留Alpha通道,不然会出现黑边或者背景不透明的问题
内容的提问来源于stack exchange,提问作者Greenkiller




