artcraft:轻量级开源工具,用程序化生成无缝像素纹理

发布时间:2026/10/21 9:15:38
artcraft:轻量级开源工具,用程序化生成无缝像素纹理 前阵子我把一个叫artcraft的小工具开源了。它原本只是我私下用来做像素风格纹理的脚本后来越写越顺手干脆包成了一个带命令行和简易界面的完整工具。如果你玩过复古游戏、做过独立游戏素材或者只是对“用程序生成美术资源”这件事感兴趣那这个东西应该能帮你省不少事。它能做的核心事情有三件根据噪声和色带生成可平铺的像素纹理、实时预览笔刷效果、导出成任意尺寸的PNG序列。整个项目不到两千行代码依赖很少跑起来很轻量适合拿来做学习样例也适合直接用在你的小游戏里。1. 项目定位与整体设计思路1.1 为什么做 artcraft接触过独立游戏开发的人大概都有这种经历美术资源永远是短板。我早期做 demo 的时候为了给场景铺一张地面纹理经常在绘图软件里磨一下午最后出来的东西还是脏兮兮的。后来开始研究程序化生成发现很多复古游戏里的材质其实都是算法算出来的比如《Minecraft》的噪点草丛、《星露谷物语》的柔和过渡本质都是噪声函数叠加调色板的结果。但网上现成的工具要么太复杂要么生成风格不可控所以我决定自己写一个。artcraft 的定位很明确不跟那些专业绘画软件抢饭碗专注于“程序化生成像素纹理”这件小事。用户只需要调整几个参数噪声频率、色带数量、平铺尺寸就能立刻得到一张风格化的材质图。生成结果既可以直接导出也可以丢进内置的编辑器里再手绘修改。这种“生成手绘”混合的工作流是我在各类商业美术工具里没看到过的——它们要么纯手工要么纯程序化两者之间缺少一座桥。1.2 技术选型与取舍技术栈上我选了 Python NumPy PyQt5。原因很简单NumPy 的数组计算本身就等同于像素矩阵运算天然适合图像处理PyQt5 负责界面和预制体预览成熟稳定底层绘图部分我直接用了 Pillow 来写PNG不引入重型图形库。整个项目只有一个主模块加三个辅助模块任何人 clone 下来后跑pip install -r requirements.txt就能启动。有些朋友问我为什么不用 WebGL 做成在线版本那样灰度传播会更广。我的考虑是独立开发者的工具首先要“本地可靠”浏览器端虽然分享方便但复杂的文件读写、绘制事件处理容易受沙箱限制而且每个浏览器的表现都不太一样。做成桌面工具后CtrlS 直接存文件CtrlZ 撤销也不受网络影响。后续如果有需要我再抽一层生成核心做成 WebAssembly 版。2. 核心功能拆解与实现要点2.1 像素纹理生成器核心算法这个模块是整个项目的引擎。它的核心思路是用多频率噪声混合出自然的不规则性然后通过“色带映射”把连续灰度值变成离散的颜色阶梯。听起来复杂拆开看其实只有三步。第一步噪声生成。我用了OpenSimplex噪声作为主噪声源而不是常见 Perlin 噪声因为它没有明显的轴向网格感生成的纹理在平铺时接缝隐藏得更好。代码里核心参数是frequency默认值 3.0越大生成的纹理颗粒越碎。以下是我生成基础噪声的示例import opensimplex import numpy as np def generate_noise(width, height, scale3.0, seedNone): if seed is not None: opensimplex.seed(seed) noise np.zeros((height, width)) for y in range(height): for x in range(width): noise[y][x] opensimplex.noise2(x / width * scale, y / height * scale) # 归一化到 0~1 noise (noise - noise.min()) / (noise.max() - noise.min()) return noise每个像素调用一次noise2其实有点慢实际实现里我会用向量化优化但这代码更容易理解。第二步生成色带。色带本质上是一组颜色断点程序会把连续的噪声值映射到这些断点之间的渐变上。比如设定四个断点[(0.0, #3a5f0b), (0.3, #5b8c1a), (0.7, #8fc641), (1.0, #c8e6a0)]那么0.0~0.3区间内是深绿到中绿的渐变0.3~0.7是中绿到亮绿以此类推。这就是像素纹理“层级感”的来源。第三步平铺。程序生成噪声时会让边缘噪声值对齐把width/height之外的区域再采样一遍最后首尾模糊融合。这一步不做的话导出后的图片在水平或垂直方向重复时会看到明显的接缝。我在代码里用了一个小技巧生成两倍尺寸的噪声图然后取中心的那个和边缘的做交叉淡入。大家可以看一下实际生成的纹理def tile_texture(noise, blend_width4): h, w noise.shape # 复制边缘像素计算融合权重 left noise[:, :blend_width] right noise[:, -blend_width:] noise[:, :blend_width] (left right) / 2 noise[:, -blend_width:] (left right) / 2 top noise[:blend_width, :] bottom noise[-blend_width:, :] noise[:blend_width, :] (top bottom) / 2 noise[-blend_width:, :] (top bottom) / 2 return noise这段代码虽然简单但注释说明了一切先融合左右、再融合上下blend_width默认设为 4生成 16x16 小纹理时接缝消除效果最好。如果图块尺寸很大可以把这个值调成 8过渡会更柔和。2.2 笔刷引擎与手感调节光能生成静态纹理还不够实际做素材时你肯定还要手动修细节。因此我给 artcraft 加了个极简手绘模式支持像素笔刷、矩形工具和油漆桶。这几个工具实现起来不难主要是手感上的细节。其中最重要的参数是笔刷硬度和大小。普通绘图软件的笔刷有柔边效果但像素画需要硬边矩形、硬边圆形笔刷。我在实现时针对圆形笔刷做了一个防锯齿处理如果鼠标移动速度过快两点之间用 Bresenham 直线插值补点避免画出来的轨迹断成一截一截。让我贴一下笔刷落点补插的代码片段方便你直接抄作业def paint_line(img, start, end, color, brush_size): x0, y0 start x1, y1 end dx abs(x1 - x0) dy -abs(y1 - y0) sx 1 if x0 x1 else -1 sy 1 if y0 y1 else -1 err dx dy while True: paint_point(img, x0, y0, color, brush_size) if x0 x1 and y0 y1: break e2 2 * err if e2 dy: err dy x0 sx if e2 dx: err dx y0 sy这里用的是最经典的 Bresenham 算法配合paint_point画实心圆点。实际画的时候如果你的绘制频率是 60FPS鼠标快速拖拽时两点距离可能有 10~20 像素不补插肯定是断的。补完以后视觉效果跟真实画笔几乎没区别。手感调节上我做了两件不少人忽略的事一是支持“长按反向擦除”按下 Alt 键时同一笔刷会变成橡皮擦二是给撤销栈设置了上限 30 步防止内存无限增长。这个数字不长不短实际绘画时足够救回大多数误操作又不会让性能明显衰减。2.3 图层与调色板管理像素纹理生成通常需要叠加两三个图层比如“基础底色 细节纹理 高光”。我在 artcraft 里实现了真正的图层系统每个图层是一张 RGBA 矩阵叠加时按从上到下的顺序混合图层底部自动缓存合成结果。默认新建画布 64x64 像素这是复古游戏最常用的纹理尺寸。调色板管理这块我大胆做成了“程序化调色板”。你可以先手动选四五个颜色然后在调色板视图里点“生成配色方案”算法通过遍历 HSV 色环自动生成相邻色和对比色并附加到你选的颜色后面。这个功能本来是灵感偷懒用的但后来发现对颜色敏感度不高的开发者特别适用能快速确定主体、阴影、高光三组配色不用从头去调。调色板数据以 JSON 格式保存方便你在其他项目里复用。比如生成了一个沼泽地面主题的调色板保存为swamp_palette.json后之后新建纹理时直接拖进去就能生成风格一致的纹理。这省去了每次重复试颜色的时间。3. 实操流程30 分钟复现一个纹理 Demo3.1 环境准备与启动首先把 artcraft 克隆到本地。假设你已经装好 Python 3.9 以上版本接下来执行git clone https://your-repo/artcraft.git cd artcraft pip install -r requirements.txt python main.py启动后界面最左边是工具栏中间是画布预览右侧是参数面板。第一次打开时默认加载了一个 64x64 的草地纹理你可以在右侧面板看到三个滑块噪声频率、色带数量和边缘强度。我的建议是从默认参数开始慢慢调不要一上来就追求极端效果。这边放一个我自己测试时的配置表格方便参考预设类型频率色带数量边缘强度适用场景沙地2.532沙漠地表岩石5.046悬崖墙面草地3.044平原地表水波1.851水面波纹3.2 从零生成一块石墙纹理我以石墙纹理为例带你走一遍完整流程。首先点击菜单栏的“新建画布”规范设为 64x64。接着在右侧面板把频率调到 5.0色带数量设为 4边缘强度设为 6点击“重新生成”按钮。这时你会看到画布上出现一块灰度图转换成四阶灰度阶的图案。然后打开调色板手动添加这四个十六进制颜色#4e342e、#6d4c41、#8d6e63、#a1887f。大概是一组棕色系颜色。点击“生成配色方案”让程序自动为你补上两组高光和阴影。回到画布后选择油漆桶工具从左下角起涂抹大块区域你会发现画布逐步填充成了有暗部亮部层次的棕色纹理。这里每个色阶相当于一个颜色断层表现石砖的受光面与阴影面。最后利用矩形工具在纹理上画几条直线作为砖缝。置前景色为暗色#3e2723选择 2px 大小的矩形笔刷沿着纵向每 8 像素画一条线再把线条横向对齐偏移就能得到石墙砖缝的基本结构。按 CtrlS 导出为 PNG 时会看到 64x64 的图片保存到了项目目录。你也可以选择“导出为平铺纹理”最终文件就是无缝拼接的。3.3 命令行批处理与脚本集成如果你不想要图形界面artcraft 还提供了命令行模式。这个模式对我这种喜欢批处理的人非常友好。比如你想一次性生成 100 张不同随机种子的草地纹理只需要写一段脚本调用python -m artcraft.cli generate --size 128 --frequency 3.0 --bands 4 --tile --output ./textures/ --count 100命令行模式支持--seed参数复用已生成纹理也支持从 JSON 配置文件读取所有参数。我在实际项目中就把某个关卡的纹理批量生成脚本做成了配置文件提交到仓库美术调整的时候只要改配置文件里的颜色断点重新运行脚本就能同步更新所有素材。这个方法比重新手绘快了一个数量级。4. 常见问题与排查技巧4.1 纹理颗粒感不自然像马赛克如果生成出来的纹理看起来不是像素风格而是类似镜头噪点的那种乱粒子说明你的frequency设置得太高噪声变化频率远大于画布分辨率。举个简单例子64x64 的画布如果频率为 10.0那每个像素之间的噪声值跳跃很大几乎没有平滑过渡。通常这个值不要超过 7.0除非你就是刻意追求那种老电视雪花效果。有一个技巧是开启“双重缩放”预览界面左下角显示的二倍平滑视图只是预览不是最终结果。在预览图里觉得颗粒大就先降低频率觉得颗粒细就适当升高。我的经验是最终视图里颗粒大小占 4~8 个像素是多数纹理最自然的状态。4.2 笔刷绘制时有延迟或画不出点画笔延迟一般是因为你用的是软渲染模式。在main.py底部有个use_opengl变量默认是 False也就是 CPU 渲染。在低端电脑上刷 64x64 画布还好但一旦放大到 300% 时鼠标移动映射会产生较重的计算。你可以把这个变量改成 True使用 OpenGL 加速但这需要额外安装pyopengl。另外绘画时关闭实时噪声预览右侧面板的“预览”复选框也会明显减轻延迟。画不出点的情况多半是把颜色透明度设成了0。检查右侧缩略图下方的不透明度滑块是不是拖到了最左边。类似的还有图层锁定的问题——主界面图层列表里如果图层前面有个锁形图标需要双击解锁后才能绘制。4.3 导出图片颜色和预览差别很大这个问题我在 0.3 版本里遇到过后来发现罪魁祸首是 Pillow 保存 PNG 时的色彩模式转换。默认画布内部用的是RGBA模式但如果你在调色板里写入的颜色值带有 alpha 通道比如#4e342e80导出 PNG 时就会出现颜色偏灰或变透明的情况。解决办法是在调色板面板的右下角统一将不透明度设为 255或者直接使用十六进制六个字符的颜色值。如果你导出的目标是用于游戏引擎比如上帝视角的角色素材建议导出时选择“预乘 Alpha”选项。这个选项会把透明度边缘的 RGB 值做平滑处理避免在游戏运行时纹理周围出现暗边。4.4 平铺接缝还是看得见部分用户反馈生成的纹理在可平铺模式下仍然能看到缝隙。这通常不是生成算法的问题而是因为硬件纹理采样设置了线性过滤而你的纹理本身是像素风格的线性过滤会让边缘像素模糊化。如果你在游戏中使用这类纹理一定要把纹理过滤模式设置为最近邻Nearest而非双线性。如果你只是从 artcraft 里查看接缝点“预览无缝”按钮可以切换画布边缘到底有没有缝隙方便你检查。5. 后续扩展思路5.1 接入物理引擎做动态艺术artcraft 目前的输出是静态图片但我已经在考虑让纹理向量层支持动态粒子解码。比如在雪地纹理上叠加一个位移场当物体走过时纹理形状会暂时改变从而模拟脚印。思路是在当前生成流程中加入一个时间维度把这个时间维度映射到物理引擎的坐标变化上。因为核心噪声函数本来就是连续的只要把噪声采样坐标替换为物体运动轨迹的坐标实际上是可以实时生成改变后的纹理的。目前已经有个技术验证分支在实验效果基本符合预期但还没有足够的时间把它打磨成正式功能。5.2 训练风格化模型另一个思路是用 artcraft 的生成结果作为训练数据去微调一个轻量级的风格化模型。因为 artcraft 可以快速产出大量风格统一但细节不同的纹理图天然适合作为数据集的“正样本”。配合一个对比学习框架可以让模型学会在保持纹理结构的同时生成新的配色。这个过程我只在本地小规模跑过一次从约 500 张生成的草地纹理里训练出一个 10MB 大小的模型输入随机噪声就能输出类似风格的 64x64 纹理。不过目前模型的风格迁移还不稳定处理复杂结构时会有拉伸后续可能需要引入额外的深度估计约束。做这个项目让我对“程序化生成”有了更实际的认识它不能完全替代美术但是在写实与风格化素材的起步阶段能省下极高的时间成本还能让项目始终保持一致的视觉语言。尤其是当你面对几十张地图素材没有灵感时用 artcraft 多试几组参数再在结果上手绘微调往往是最高效的一条路。如果你正好在寻找一个小巧、可拆解、拿来即用的像素纹理生成方案不妨去读一读这个工具的源码也许里面就有你需要的某个噪声函数或颜色映射实现。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询