开启辅助访问     
收藏本站

站内搜索

搜索

Minecraft(我的世界)苦力怕论坛

[闲聊] 万象添补加入纸类建材,不透明方块连接纹理的技术突破

 发表于 2025-11-20 22:31:57 来自手机|显示全部楼层|阅读模式 IP:天津
本帖最后由 Cat_Anchor 于 2025-11-20 22:38 编辑

这里是我的第 114 篇闲聊帖。距离上次写闲聊又过去了 9 天,现在我终于来写一篇新的闲聊帖了。


万象添补0.17.7 的开发工作刚刚完成,主要是加入了三种纸质的建筑方块,纸盒、纸板和纸板口。纸盒房子,外部视角

这些都是我从一个想法延伸出来的特性,它们的基础物品是“竹浆纸”,一种用竹子就能合成的纸。我在配方里加了水桶,因为听说竹浆要用水。

用 4 个竹子和一桶水合成竹浆纸之后,就可以用它合成上面提到的三个建筑方块了。其实它们的价值不仅体现在概念本身上,更体现在我实现了一种新的制作带连接纹理的方块的方法。

带连接纹理的方块的制作,一直是附加包制作的难点。以前我们没什么接口,于是只能用 minecraft:queued_ticking 不停检测,通过方块事件设置方块状态,再用 bone_visibility 修改模型骨骼的可见性。不仅如此,我们还需要定义复杂的方块模型,免不了遇到深度冲突。

深度冲突就是两个不同纹理的平面互相重叠并闪烁的现象,“深度”代表“Z 轴上的”。说实话,我一开始以为“深度冲突”就是冲突程度非常深的意思。

无框玻璃的制作历程很能反映我们在“带连接纹理的方块”方面的技术进步。一开始,我们只能直接修改玻璃纹理,把边框去除,这也是最原始的一种方法。它的缺点很明显,那就是一整块玻璃都没了边框,分不清它与普通方块的界限。

后来我们使用骨骼可见性,这也是无框玻璃板至今还需要的方案。很久以来的进步,无非是把方块事件升级成了自定义组件而已。

但是最近,情况有了改观。现在最新的技术是,对于无框玻璃,我们可以直接使用方块剔除,不需要任何方块状态;对于无框玻璃板,我们需要方块状态、骨骼可见性和方块剔除的综合运用。


相对于一开始,这已经是很大很大的,颠覆性的进步了。

然而还有一座更为艰巨的技术大山横在我们面前。

不透明方块连接纹理

对于玻璃那样的方块,方块之间相互连接的纹理很简单,因为我们实际上是在渲染玻璃的边框。一个位置要么有边框,要么没有,就这么简单。

对于染色玻璃,情况会复杂一点,不过也只是一点点。一个位置要么有边框,要么带半透明的颜色,这也很简单。就算我们把半透明颜色与边框叠加渲染,看起来也不会非常奇怪,毕竟那只是一种半透明的覆盖层。

对于不透明方块,方块中间的纹理当然是恒定不变的;可是方块边框的纹理不一样,它要么是边框纹理,要么是中间的纹理。如果只是边,那也没多大问题;问题出在角上。

为了让方块边框纹理正确渲染,我们要让两个面在角落重叠。正常来说这没什么问题,因为角落那里尝试渲染的是同一个纹理;但是一条边尝试渲染方块中间的纹理,而另一条边尝试渲染边框纹理时,方块角落就会尝试渲染不同的纹理。这就会产生深度冲突。

而就是这个深度冲突,成了怎么也攻克不了的难题。


不过最后会解决的。

我尝试创建考虑了角落情况的方块模型。一个顶面,我们需要创建 8 个立方体,用于渲染边框;另外 8 个用于渲染内部,也就是连接时候的纹理;最后还需要 1 个立方体渲染中间,恒定不变的那部分。这样算下来,一个面就要 17 个立方体,6 个面就是 102 个立方体,而每个立方体都代表着一个骨骼可见性中的 Molang 表达式。

就算一切变换的计算得当,就算把各种方位问题搞清楚,就算克服重重困难写好了 102 条 Molang 表达式,最后我们也无法成功。

因为骨骼可见性的条件数量,被卡死在了 64 个。我们最多只能定义 64 个规则,对应 64 条 Molang 表达式。

102 大于 64。我只好放弃这条路线,研究其他方向。


说是其他方向,研究起来哪有那么容易?踌躇一会儿之后,我选定了第二条研究路线(是的,“第二条”说明了此路不通,还会有第三条),那就是把外层边框与内层连接纹理错开一点。结果方块上产生了难看的黑色细线,这是我不能接受的。更糟糕的是,深度冲突的问题也没有完全得到解决。

这是一个历史悠久的漏洞,我还原纪念碑谷时就遇到过。在某些方向上,某些坐标上(我没有发现明显规律),方块的某些立方体坐标会丢失精度,导致原本有一定距离的两个立方体重叠。这里的立方体在某个轴上的尺寸为 0,它们实际上指的是平面。一旦两个不同纹理的平面重叠,深度冲突就产生了。

最后,由于这个漏洞,我不得不放弃第二条路线,转而提出第三条路线。


而第三条路线是可行的。

我完全抛弃了旧有的那些模式。为什么边框必须是附着在纹理上的?我们完全可以把它做成立体的!于是我立刻开始制作,由于一个正方体只有 12 条棱,我们只需要 12 个代表边框的立方体,和 1 个代表方块本身的立方体。

更令我惊讶的是,写完 Molang 表达式之后,我发现它居然可以方块剔除规则化!也就是说,用 Molang 表达式能完成的,方块剔除也可以!这看似不怎么重要,而且这样做之后数据的可读性大大下降了,但是——

这样我们就不需要方块状态了!

写完整个数据定义之后,我惊叹于这个一开始笨重无比的文件现在多么简洁优美。





format_version 是格式版本,identifier 是方块 ID,除去其他基本属性不谈,这个方块使用的模型 ID 是 geometry.paperbox,而关于方块连接纹理的全部秘密,都藏在 complementary:paperbox_culling 里面……


但是很可惜,最后我做出来的结果,还是存在一定的深度冲突的问题,而且现在我没有时间修复它。不过我已经知道了一种修复方法,修复它也只是时间问题了。明天我们早放学,我就可以找时间修复它了。说不定,在这篇帖子核审完成之前,我就解决了这个问题(前提是核审不给力)。

对了,上个版本我还加入了“相位平面”,不过那只是我一时想出的点子,它的代码花了我一番功夫,最后结果可能还不值得我在上面花的时间。不过我最终还是把它实现出来了。

你们可能发现万象添补的版本号停留在了 0.17.x。这是因为,在计划中,0.17 之后就应该是 1.0 了,但是我还没准备好宣布万象添补正式发布。也许它会继续停留在 0.17.x 一段时间,不过这某种意义上也是好事,因为这时候发现什么重大漏洞了还可以用一用“现在还是测试版”的借口。

评分

参与人数 1铁粒 +30收起理由
 Saka*** + 30shiastini

查看全部评分

苦力怕论坛,感谢有您~

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

| 由 木韩网络 提供支持 | GMT+8, 2026-2-3 07:47

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4