岩钉就像检查点一样。当你刚开始玩游戏时,它们尤其有用。
技术美术深度解析:Cairn 如何利用 3D 混合贴图渲染游戏玩法指定的岩石材质

The Game Bakers의 안토니 베이어는 그의攀岩模拟游戏《Cairn》을 개발하면서 “无锚点表面”의 기술적 예술에 대해 탐구했다.了解他们如何利用 Unity 中的 3D 混合贴图和计算着色器,克服了视觉效果与游戏玩法协调一致的难题。
你好!我是安东尼·拜尔,The Game Bakers 的技术艺术总监。我原本的背景是平面设计(网页设计、印刷设计)。我第一次接触电子游戏是在2010年,当时作为一名3D建模师参与了移动端游戏的开发。当时,我对编程一窍不通,但对在游戏引擎中处理图形非常感兴趣,于是我开始学习 JavaScript,并在业余时间尝试制作了一些小型 Unity 项目。如今,我花在编写代码上的时间比制作3D模型还要多!您可以在我的ArtStation主页上查看我的部分作品。
我是在《Furi》开发初期,大约2014年左右,开始与The Game Bakers工作室合作的。《Furi》于2016年发布后,我们开发了《Haven》(2020年上线),并于2026年1月发布了我们的新作《Cairn》——一款攀岩模拟视频游戏。
在《Cairn》中,什么是岩钉?
在《Cairn》中,你几乎可以攀爬每一面墙壁,而我们实现了耐力机制,让这种体验更具挑战性。攀爬了一段时间后,阿瓦(玩家角色)最终会感到疲惫。为了休息一下,她可以用一种叫做岩钉的金属钉将自己固定在岩壁上。(游戏玩法说明:冰锥并非必需品,没有它们也能攀登,但这需要对凯恩(Cairn)的攀登控制点有更深入的了解。
为了增加某些岩壁的难度并迫使玩家尝试“徒手独攀”路线,我们希望禁止在环境中的指定的区域打入岩钉。在这篇博文中,我将详细介绍我们是如何开发这款游戏中被称为“No-Piton Surfaces”的这个小技术模块的。
《Cairn》的主角阿瓦拒绝在“禁钉区”上打入岩钉。
如何向环境中添加不同类型的表面
当你想对地形进行变化时,首先会想到什么?你可以……
- 添加新对象和几何体
- 添加“顶点颜色绘制”
- 使用“混合纹理”
Cairn 绝对不是那种典型的“由高度图控制”的地形;它实际上是一个由多个模型部件拼接而成的山体(更多详情请见这篇 ArtStation 帖子)。

这使得通过添加额外的物体或几何体来实现变体变得困难,因为这给本已复杂的关卡设置流程增加了更多限制(而我们希望在实际攀爬关卡设置的基础上,自由地设计“无岩钉表面”)。
Blendmap 和 Vertex Color 是类似的技术,二者都是着色器中用于采样以生成渲染变体的遮罩。
就我们而言,我们无法使用顶点颜色绘制,因为:
- 需要绘制的顶点太多了。
- 存在太多几何体重叠的情况(手持网格投影到拼装地形上)。
- 我们的模块化岩石采用了LOD,因此顶点密度并不一致。
2D混合贴图
最后,我们决定采用Blendmap方案!
值得庆幸的是,我们已经有一个用于场景美术的定制化工具——TexturePainter。借助该工具,我们可以在编辑器中绘制混合贴图,并将它们分配给一组渲染器(无论是手动选中的渲染器,还是位于 TexturePainter 边界内的渲染器,均可自动分配)。
在 The Game Bakers,我们热衷于在 Unity 中开发自定义工具——[ExecuteAlways] 通常是我在每个脚本中添加的第一行代码!
我们主要使用 TexturePainter 在地面上绘制草地和积雪层,但由于在 TexturePainter 中可以自由旋转,因此我们也能在墙面上进行绘制。

经过一些细微的修改后,我们创建了“无锥体曲面”混合贴图,从而能够动态更改纹理和着色效果。
由于这是一个烘焙后的二维纹理,因此很容易在给定的世界坐标处采样纹理的值,从而判断玩家是否可以放置岩钉。
这个构想奏效了!但在这一阶段,效果仍然相当有限,因为这是一种2D遮罩投影,而且整座山只能使用一个这样的遮罩,因此精度较低。
当时,我们还不确定“无尖峰表面”能否最终加入游戏。从视觉效果来看,它们并不讨喜,而且我们需要进行大量游戏玩法和关卡设置测试,才能确保它们能为游戏添加实质性的价值。
但我们至少可以开始迭代它的外观应该是什么样子的。
暴露一些渲染参数可以让我们尝试为这种类型的表面呈现不同的视觉效果。
当你的第一个解决方案完全行不通时
就在我们试图从美术方向改进渲染效果的同时,在关卡设置方面,“2D投影”的局限性却变得越来越棘手。鉴于我们关卡设置的特性,我们需要对以下“无锚点表面”进行3D控制:
- 山体内部(洞穴中)可见的无钟乳石岩面
- 无需Piton即可包裹凹面/凸面墙体/架构的曲面
…
时间跳跃
在游戏开发领域,总是有很多新点子和新的事情要做。我喜欢像蝴蝶一样工作——每次遇到瓶颈,我就先把问题搁置一边,去别处做点别的!
…
三到六个月后……
在其他新功能方面,我们使用 Texture3D 来表示距离场。我们放置了许多体积(立方体和椭球体),并据此生成一个距离场纹理,其中每个像素都包含到最近体积的距离。每个音量可以是增益或衰减。
这就是我们所说的“拓扑视图”:一种由世界空间中的 Texture3D 控制的屏幕空间图像特效。
这些 3D 距离场纹理分辨率较低,且在 Runtime 按需生成(它们也没有在编辑器中烘焙,CPU 端也无法读取)。
3D混合贴图
此时,是时间尝试我们针对无Piton曲面的3D混合贴图解决方案了。
在着色器端,将二维纹理转换为 Texture3D 非常简单。现在只需在世界坐标系中添加一些噪声来隐藏这些低分辨率的纹素,瞧,大功告成!
编辑无锚点曲面
从视觉效果上看,这个方案可行,但在游戏玩法方面却中断,因为纹理无法被 CPU 读取,导致我们无法在纹理上检测到玩家的位置。
距离场采样是在CPU端通过迭代每个基本体(立方体、椭球体)来完成的。然而,由于我们在岩石着色器中对世界坐标添加了噪声,边缘处出现了明显的偏移;显然,这缺乏精度。

将视觉效果与游戏玩法相融合
为了解决这个问题,我们使用了一个计算着色器,以获取与岩石着色器中完全相同的数值。
当玩家想要放置岩钉时,我们会向岩壁进行射线投射来确定岩钉的位置,并检查玩家是否位于“禁止放置岩钉区域”内。如果是这种情况,我们会将请求发送到位于插桩位置的计算着色器。当计算着色器的结果返回时(在同一帧或下一帧),我们会验证或禁用放置岩钉的功能。
现在我们有一个纹素级精确的示例:“岩石着色器”和“无Piton检查的计算着色器”,两者的代码完全相同。
结果证明,这个解决方案有点过于精确了!
假设你正身处普通岩壁与“禁止使用岩钉”岩壁之间,你想打入一枚岩钉,却无法做到,因为游戏中的世界定位系统已判定你所在的位置属于“禁止使用岩钉”区域。当你明明可以在两英寸外就打入一枚岩钉时,这似乎非常不公平。
为了解决这个问题,我们会在玩家周围的小范围内触发多个采样点,以寻找可用的有效位置(如果存在的话)。
在这里可以看到,绿色的标记位于一块没有岩钉的岩石上,而上面的蓝色标记则位于一块普通的岩石上;我们将选择第二个位置来打入岩钉。
总有值得精益求精的地方
既然一切看起来都很不错,有足够的时间进行精修和润色。
我们实现了一种同时加载多个“无皮顿区”的方法。只有最近的区域才是“真实”的,其余区域则以LOD贴图的形式渲染。虽然这种方案远非完美——因为贴图是延迟渲染的,无法像岩石着色器那样接收光照——但它已足以满足我们的需求。
无Piton 3D混合贴图过渡:从LOD0(在岩石着色器内部渲染)到LOD1(使用延迟贴花渲染)
以上就是关于“无Piton曲面”的全部内容。如果你在玩《Cairn》,并且找到了在“无岩钉表面”上安装岩钉的方法,请告诉我——总是有需要改进的地方!
感谢阅读!
《Cairn》现已登陆PC和PlayStation®5平台,免费DLC“On The Trail”将于今夏推出。请访问我们的 Steam 策展页面,探索更多 Made with Unity 制作的游戏,并前往 Unity 博客和资源中心阅读更多 Unity 开发者的故事。
