跳过正文

WFC瓦片生成标准解读

·2216 字·5 分钟
杂谈 Unity Blender Shader Houdini 算法
AxonSin
作者
AxonSin
梦想是复活在赛博世界,成为一名赛博垃圾人。

大致工作流:AI生成2D俯视图——生成地板——墙壁重新组装为Prefab

要不地板和墙壁单独计算?

先生成带有墙壁的草图,然后对于特性房间可以用地板区分?

还是直接Random?

有关Blender和Unity的模型协作,请看https://www.yuque.com/shuangfeidu/txwa8w/qeomm77fu218fa4v

  • 上(1)右上(2)右(4)右下(8)下(16)左下(32)左(64)左上(128)
  • 8邻域位掩码(8-directional bitmask)

技术解读
#

首先需要知道WFC算法是做什么的。简单来说,它是一种根据一小组“规则”来程序化生成复杂地图(比如游戏关卡、纹理等)的算法。它最核心的规则就是“邻接规则”——即哪些瓦片(tile)可以和哪些瓦片放在一起

这张图展示的就是一套非常经典和高效的瓦片(tileset)定义标准,通常被称为“Blob Tileset”或“Bitmask Autotiling”。它的目的是用一种巧妙的方式,自动处理所有瓦片的邻接关系。

核心概念:什么是“瓦片”和“规则”?
#

在这张图中:

  • 黄色部分可以理解为“实体”或“地面”。
  • 蓝色部分可以理解为“虚空”或“背景”。

每一个小方格都是一个“瓦片”。WFC算法的目标就是将这些瓦片拼接成一个看起来自然、没有断裂的、更大的“Blob”(一团)形状。

规则就是:黄色的边缘必须和黄色的边缘相连,蓝色的边缘必须和蓝色的边缘相连。

为了实现这一点,我们需要为每一种可能的瓦片组合都创建一个瓦片。一个2x2的瓦片有4个角,每个角都可以是黄色或蓝色,所以理论上我们有 2^4 = 16 种基本形态。这正是图片最上面一行展示的16种核心瓦片。

2. 解读图片中的数字:Bitmask(位掩码)
#

这张图最让人困惑的就是这些数字。这些数字是每种瓦片的唯一ID,而这个ID是通过一种叫做**“位掩码”(Bitmask)**的技术计算出来的。

这个方法给瓦片的每个关键位置分配一个固定的数值(通常是2的幂),然后通过将“激活”位置的数值相加,得到最终的ID。

非常棒的分析!您已经完全抓住了最核心的要点,这正是程序化生成中常用的 8邻域位掩码(8-directional bitmask) 的思想。

您的推理方向完全正确:通过为每个邻近位置(边和角)分配一个2的幂的数值,然后将它们相加,来为每种瓦片形态生成一个独一无二的ID。

不过,您会发现,如果将您提出的这套数值方案代入原图,会无法完美匹配所有ID。

上(1), 右上(2), 右(4), 右下(8), 下(16), 左下(32), 左(64), 左上(128)

这是因为这张经典的 “Blob Tileset” 图,使用了一套稍微有些“古怪”和非连续的数值分配方案。您的方案在逻辑上更清晰、更现代,但这张图遵循的是另一套标准。

让我们用您正确的思路,来解开这张图特定数值谜题。这张图最上面一行的16个瓦片,实际上只关心四个角的状态。

总结
#

为了让你彻底理解,我们把整个逻辑梳理一遍:

  1. 目的: 使用WFC算法,通过拼接小瓦片,自动生成看起来自然的、连贯的“Blob”地图。
  2. 核心规则: 瓦片的边缘颜色必须匹配(黄对黄,蓝对蓝)。
  3. 瓦片ID (位掩码): 为了让计算机高效地理解和查询“哪些瓦片可以和我的右边缘匹配?”,我们给每种瓦片一个数字ID。这个ID是通过检查瓦片的边缘(或角)是否为黄色,然后将对应位置的预设值相加得到的。这就是位掩码技术。
  4. 图片的作用: 这张图就是一个**“ID查询表”“标准解读”**。它告诉你:
    • ID为 7 的瓦片长什么样(上、右、下是黄边)。
    • ID为 23 的瓦片长什么样(上、右、下、左都是黄边,但它不是全黄的中心块)。
    • ID为 5 的瓦片和ID为 20, 80, 65 的瓦片在逻辑上属于同一组,它们可能只是旋转或翻转的关系。

如何使用它:
当WFC算法要在一个空格子填充瓦片时,它会检查这个格子的邻居。比如,它发现:

  • 上方的瓦片有一个黄色的下边缘。
  • 右边的瓦片有一个蓝色的左边缘。

算法就会去这个规则集里寻找一个满足“上边缘为黄,右边缘为蓝”的瓦片,然后从所有满足条件的瓦片中随机选择一个放进去。这个过程不断重复,直到整个地图被填满。

我们的房间要求
#

一般的WFC瓦片中,瓦片不一定是一个最小单位。但是在这个游戏中,每一个瓦片/或者说是房间都是最小单位。也就是说,一个瓦片中,最多只有四个出口,并且没有多出口的拼接。

目前我想的方法是墙壁+地板的组装方式。即,墙壁负责进行控制出入口的生成(上图的黄色部分),地板则负责控制这个房间单位的特性(黑房间,灰房间?)。脚本和shader则和地板强绑定。最终以上内容重新组装为Prefab。

最终成品 (Prefab)
├── 墙壁 (Wall)
│   └── 职责: 控制出入口生成 (连接性)
└── 地板 (Floor)
    ├── 职责: 控制房间单位特性
    │   ├── 强绑定: 脚本 (Script)
    │   └── 强绑定: 着色器 (Shader)
    └── 示例: 黑房间、灰房间等

一个房间有东南西北四个方向的开口,每个方向可以选择“开”或“关”。总共有 16 种可能性,具体如下:

所有开口可能性
#

1. 无开口(四个方向都关闭)
#


2. 仅一个方向开口
#

  • 西

3. 两个方向开口
#

  • 东 + 南
  • 东 + 西
  • 东 + 北
  • 南 + 西
  • 南 + 北
  • 西 + 北

4. 三个方向开口
#

  • 东 + 南 + 西
  • 东 + 南 + 北
  • 东 + 西 + 北
  • 南 + 西 + 北


5. 四个方向都开口
#

  • 东 + 南 + 西 + 北

总共有 16 种组合(即

image
),包括所有可能的子集(从完全关闭到全部开启)。

一共16种组装房间。
#

示例
#

Tile Samples

sample demo。可以调整种子进行不同的地图生成。但是还没有做手动约束(哪种房间只能生成几个)

瓦片重声明

以路牌作为所有prefab测试,目前已经可以进行Unity-Houdini间的连接。

Todo:Random房间属性并接入Prefab,随机摆放饰品添加画面丰富度,接入TOPS进行AI生成模型的批量减面器。

Reply by Email

相关文章

常见的引擎物理算法
·3458 字·7 分钟
杂谈 Unity Blender Animation Houdini Git 渲染 算法 物理 色彩 MMD
Blender导入Unity指南
反射算法
·46 字·1 分钟
杂谈 Unity Blender Shader 渲染 算法
Blender导入Unity指南
色彩空间
·13451 字·27 分钟
杂谈 Shader Houdini 渲染 算法 物理 色彩 技巧 配置
算法原理解析