☰
SpaceshipGenerator 完全指南:用 Blender 脚本从随机种子程序化生成 3D 太空飞船
2026/10/14 3:15:00 网站建设 项目流程
  • 3D建模
  • 图形学

【免费下载链接】SpaceshipGenerator

A Blender script to procedurally generate 3D spaceships

项目地址:https://gitcode.com/gh_mirrors/sp/SpaceshipGenerator
点击查看免费下载

SpaceshipGenerator 是一款以 Blender 插件形式提供的程序化生成工具,只需一个随机种子,就能在几秒内生成一艘带完整材质、法线贴图与自发光窗灯的 3D 太空飞船。本指南以仓库根目录的 README.md 为主线,结合 spaceship_generator.py 与init.py 的源码实现,完整覆盖插件的安装启用、面板参数、生成算法原理、可编程调用与批量渲染等实战内容。读完本文,你将掌握如何安装并调参生成个性化飞船、如何通过种子复现同一艘飞船、如何在 Python 环境中以脚本方式批量产出飞船模型,以及算法每一步的底层实现逻辑。

一、项目概述:一个「方盒子 → 宇宙舰队」的生成器

SpaceshipGenerator 是一个 Blender 脚本,其核心理念一句话可以概括:从随机种子(random seed)程序化生成带纹理的 3D 太空飞船模型。它最初是作者 Michael Davies 为 /r/proceduralgeneration 社区 2016 年 6 月月度挑战赛而写的趣味项目,后经社区贡献者修复 Bug、补全 GUI 并完成 Blender 2.80 移植,最终以 MIT 许可证发布。

从插件元数据init.py 可以看到当前版本信息:

  • 插件名称:Spaceship Generator,版本1.1.3;
  • 目标 Blender 版本:2.80 及以上(blender: (2, 80, 0));
  • 菜单位置:View3D > Add > Mesh,分类为 Add Mesh。

脚本主体是单个文件 spaceship_generator.py,共 819 行,仅依赖 Blender 内置的bpy、bmesh、mathutils模块,无任何第三方 Python 依赖,因此安装即用、易于阅读和二次开发。

二、安装与启用:三步接入 Blender

README 给出的安装流程针对 Blender 2.80+,具体操作如下:

  1. 安装 Blender:前往 blender.org 下载并安装Blender 2.80 或更高版本(2.7x 老版本不支持);
  2. 下载插件压缩包:获取最新发布的add_mesh_SpaceshipGenerator.zip;
  3. 安装 ZIP 包:在 Blender 中进入Edit > Preferences... > Add-ons > Install...,选择下载的 ZIP 文件;
  4. 启用插件:在 Add-ons 面板中搜索"spaceship",勾选启用"Add Mesh: Spaceship Generator";
  5. 生成飞船:在 3D 视图中通过Add > Mesh > Spaceship添加飞船;
  6. 调节参数:展开视口左下角出现的Spaceship 选项卡,即可调整程序化生成的各项设置。

需要说明的是,本仓库为源码形式(spaceship_generator.py+__init__.py),与 Release 中打包的 ZIP 内容一致。启用后,init.py 的register()会将操作符mesh.generate_spaceship注册进VIEW3D_MT_mesh_add菜单(即Add > Mesh下的 "Spaceship" 条目),同时在撤销栈中登记(bl_options = {'REGISTER', 'UNDO'}),因此生成操作可以撤销重做。

三、面板参数全解:控制生成结果的核心旋钮

在 3D 视图底部弹出的 Spaceship 面板中,GenerateSpaceship操作符(init.py)暴露了 11 个参数。这些属性直接映射到generate_spaceship()函数的同名参数。下表完整列出每个参数的默认值、取值范围与生成影响:

参数(面板名)类型默认值取值范围/软上限生成影响
random_seed(Seed)字符串''(空)任意字符串空串则每次随机;非空则同一种子永远生成同一艘飞船
num_hull_segments_min(Min. Hull Segments)整数3min=0, soft_max=16船体主骨架挤出段数下限
num_hull_segments_max(Max. Hull Segments)整数6min=0, soft_max=16船体主骨架挤出段数上限
create_asymmetry_segments(Create Asymmetry Segments)布尔True开/关是否在船体上生成外凸的非对称结构
num_asymmetry_segments_min(Min. Asymmetry Segments)整数1min=1, soft_max=16单个非对称段的最小连续挤出次数
num_asymmetry_segments_max(Max. Asymmetry Segments)整数5min=1, soft_max=16单个非对称段的最大连续挤出次数
create_face_detail(Create Face Detail)布尔True开/关是否在船体面上生成引擎、天线、炮塔等细节
allow_horizontal_symmetry(Allow Horizontal Symmetry)布尔True开/关是否允许约 50% 概率做 Y 轴左右对称
allow_vertical_symmetry(Allow Vertical Symmetry)布尔False开/关是否允许上下对称(源码注释提示会产生"飞船岛屿"问题,故默认关闭)
apply_bevel_modifier(Apply Bevel Modifier)布尔True开/关是否添加倒角修改器使造型棱角分明
assign_materials(Assign Materials)布尔True开/关是否赋予完整材质(关闭则用空白材质)

值得注意的调参要点:

  • 段数上限的语义:randrange(num_hull_segments_min, num_hull_segments_max)决定实际段数,因此段数实际落在[min, max)区间;
  • 垂直对称默认关闭:源码 spaceship_generator.py 注释明确写道垂直对称"会导致飞船'岛屿'(spaceship islands)",即船体可能被复制成上下分离的两半,因此默认allow_vertical_symmetry=False;
  • 软上限 soft_max=16:面板滑块建议范围到 16,但min只约束了下界,理论上仍可输入更大的数值——这正是 README "Extreme examples" 一节展示极端取值效果的前提。

四、工作原理:从盒子到飞船的七步流水线

README 用一个分步动画(step-by-step-animation.gif)直观演示了生成过程,其文字描述为七步。对照源码,每一步都能找到精确的实现位置:

Step 1 — 从一个盒子开始。spaceship_generator.py 创建单位立方体 BMesh,并用三个独立的随机缩放系数uniform(0.75, 2.0)拉伸 XYZ 三个轴,得到不规则的初始坯体。

Step 2 — 构建船体:沿法线反复挤出前后端面。对法线朝 X 轴(abs(face.normal.x) > 0.5)的端面,执行num_hull_segments次循环挤出(spaceship_generator.py)。每次挤出默认长度uniform(0.3, 1),途中以约 50% 概率随机施加 Y/Z 缩放(uniform(1.2, 1.5),末端段倾向收缩)、侧向平移(Z 方向uniform(0.1, 0.4)倍段长)与 ±5° 的 Y 轴旋转扰动;约 10% 概率改为调用ribbed_extrude_face()生成"肋骨"结构的船体段。

Step 3 — 为船体添加非对称结构。若create_asymmetry_segments开启(spaceship_generator.py),遍历所有面,跳过宽高比大于 4 的细长面,以约 15% 概率选中面并连续挤出randrange(min, max)次,每次以 75% 概率整体缩小(1 / uniform(1.1, 1.5)),形成炮台基座、副船体等凸出结构。

Step 4 — 为船体添加细节:按面朝向分类,生成引擎、天线、炮塔、灯光等。这是 README 描述中信息量最大的一步。源码 spaceship_generator.py 先按法线朝向把每个面归入engine_faces、grid_faces、antenna_faces、weapon_faces、sphere_faces、disc_faces、cylinder_faces七个桶,再分别调用对应的细节生成函数(详见下一节)。

Step 5 — 有时应用水平对称。约 50% 概率调用bmesh.ops.symmetrize(..., direction="Y")(spaceship_generator.py),把左半船体镜像到右半,产生左右对称的经典飞船造型。垂直对称同理,但默认关闭。

Step 6 — 添加倒角修改器,让造型棱角分明。spaceship_generator.py 为物体添加 Bevel 修改器:宽度uniform(5, 20)、offset_type='PERCENT'(按百分比偏移)、segments=2、profile=0.25(略偏圆滑的轮廓)、limit_method='NONE'(全边倒角)。这一步把程序化几何的硬边打磨成科幻舰船常见的"装甲接缝"质感。

Step 7 — 为最终结果赋予材质。调用create_materials()(见第六节)生成并绑定 hull、hull_lights、hull_dark、exhaust_burn、glow_disc 五套材质,随后将物体原点设为质心并归位到世界原点(spaceship_generator.py)。

Step 8 — (彩蛋)用你的新飞船舰队征服宇宙。README 最后一句的调侃:程序化生成的意义在于以近乎零成本批量产出无限舰船。

五、面分类与七类细节生成器:让船体"活"起来的秘密

Step 4 是整个生成器最出彩的部分。源码先用一个"转盘"(val = random())配合法线朝向完成分类与基础材质指派(spaceship_generator.py):

面朝向判定条件分类逻辑(按随机值 val 依次命中)
尾部face.normal.x < -0.95第一个面必为引擎;之后val>0.75引擎、>0.5圆柱、>0.25网格、否则窗灯面
前部face.normal.x > 0.9val>0.7且朝外 → 天线并涂窗灯;>0.4网格;否则窗灯面
顶部face.normal.z > 0.9val>0.7且朝外 → 天线;>0.6网格;>0.3圆柱
底部face.normal.z < -0.9val>0.75发光圆盘;>0.5网格;>0.25炮塔
侧面abs(face.normal.y) > 0.9第一个面必为炮塔;val>0.75炮塔、>0.6网格、>0.4球体、否则窗灯面
细长面宽高比 > 3直接跳过("看起来会很蠢")

随后,七类细节由对应的 BMesh 几何操作实现:

  • add_exhaust_to_face(spaceship_generator.py):用subdivide_edges把尾面切成网格(cuts = randint(1, 4 - 宽高比)),对每个网格单元挤出排气管:外扩1/uniform(1.3,1.6)、内缩1/uniform(1.05,1.1),侧壁指定exhaust_burn发光材质,形成嵌套的发动机喷口;
  • add_grid_to_face(spaceship_generator.py):2~4 刀网格细分后每个单元挤出uniform(0.025, 0.15)高、缩小 0.8 倍,侧壁随机使用hull_lights或hull材质,模拟外挂装甲板与舷窗阵列;
  • add_cylinders_to_face(spaceship_generator.py):在 1~3 × 1~3 的网格节点上用create_cone生成 6~12 段的圆柱阵列,可充当管线或散热器;
  • add_weapons_to_face(spaceship_generator.py):生成完整炮塔——锥形基座 + 左右护盾 + 可俯仰(upward_angle = uniform(0, 45)度)的炮塔舱 + 双联装炮管,每个炮塔绕 Z 轴随机旋转uniform(0, 90)度;
  • add_sphere_to_face(spaceship_generator.py):create_icosphere(细分 3 次)生成半径uniform(0.4, 1.0) × 面宽的球体,部分嵌入船体表面;
  • add_surface_antenna_to_face(spaceship_generator.py):4~10 × 4~10 网格中约 10% 的节点长出尖塔(diameter1=0的锥体,高uniform(0.1, 1.5) × 面尺寸)加底座,天线与底座材质随机取hull或hull_dark;
  • add_disc_to_face(spaceship_generator.py):32 段的双层锥体构成发光"着陆坪"圆盘,顶面使用glow_disc发光材质。

这些函数全部基于extrude_face(spaceship_generator.py,沿面法线平移挤出)、scale_face(spaceship_generator.py,在面局部坐标系缩放)与get_face_matrix(spaceship_generator.py,由面法线与边向量构造 4×4 变换矩阵)三个几何原语构建,理解这三个原语即可快速读懂全部细节逻辑。

六、材质系统与纹理:全局立方体 UV 的着色方案

README 特别指出:所有纹理都使用全局空间立方体 UV(global-space cube UV)应用,不生成传统 UV 坐标。对应源码中每张贴图节点的projection = 'BOX'([spaceship_generator.py](https://link.gitcode.com/i/a880f98d20d98a98e0c987c6a1ac5a08#L420、L471、L487)),即三平面投影——物体无论怎么建模,纹理都会沿世界轴方向正确贴附,这正是"零 UV 展开"方案可行性的关键。

create_materials()(spaceship_generator.py)为 Material 枚举 的五个成员逐一创建基于 EEVEE 节点树的材质(通过ntree.get_output_node('EEVEE')取输出节点):

材质索引用途关键实现
hull0标准船体外壳基色 + 法线贴图
hull_lights1带发光舷窗的外壳基色 + 法线贴图 + 窗色漫反射 + 自发光
hull_dark2暗色外壳(排气口/天线等)基色各通道 ×0.3
exhaust_burn3发动机燃烧发光材质Emission直接设为辉光色
glow_disc4着陆坪发光材质Emission直接设为辉光色

颜色生成同样是程序化的:船体基色hull_base_color = hls_to_rgb(random(), uniform(0.05, 0.5), uniform(0, 0.25))——随机色相、5%~50% 饱和度、0~25% 亮度,保证每艘船配色独特但不刺眼;辉光色glow_color = hls_to_rgb(random(), uniform(0.5, 1), 1)则取高饱和高亮度,用于发动机与圆盘。

三张贴图各司其职(位于 textures/ 目录,均为 4096×4096):

  • hull_normal.png:法线贴图,为表面增加额外"greebles"(科幻模型常用的细碎凹凸细节),通过ShaderNodeNormalMap接入 Principled BSDF 的 Normal 输入,且颜色空间设为Raw(spaceship_generator.py);
  • hull_lights_diffuse.png:加法性漫反射贴图,其 RGB 决定舷窗颜色——节点中先用ShaderNodeRGB填充船体基色,再以贴图 Alpha 为因子混合(spaceship_generator.py);
  • hull_lights_emit.png:自发光贴图,输出直接接到材质的Emission输入,让窗户在暗处真正"发光"(spaceship_generator.py)。

七、种子复现与 Python 脚本调用

README 的 Tips 强调:给generate_spaceship()传入种子即可稳定复现同一艘飞船,例如generate_spaceship('michael')。其原理在源码第 528-529 行:if random_seed: seed(random_seed)——只要种子的字符串非空,生成前就重置 Python 随机数生成器,此后所有random()/uniform()/randint()调用序列完全确定,从而得到逐面、逐细节都一致的飞船。

generate_spaceship()的完整签名(spaceship_generator.py)如下,与面板参数一一对应:

def generate_spaceship(random_seed='', num_hull_segments_min=3, num_hull_segments_max=6, create_asymmetry_segments=True, num_asymmetry_segments_min=1, num_asymmetry_segments_max=5, create_face_detail=True, allow_horizontal_symmetry=True, allow_vertical_symmetry=False, apply_bevel_modifier=True, assign_materials=True):

该函数返回生成的bpy.types.Object(名为 'Spaceship' 的网格对象)。在 Blender 的 Scripting 工作区中,你可以这样在脚本模式下批量生产:

import spaceship_generator # 用种子复现同一艘船 ship = spaceship_generator.generate_spaceship('michael') # 关闭细节与材质,快速生成"素模"用于实验 spaceship_generator.generate_spaceship( random_seed='hull-only', create_face_detail=False, assign_materials=False, apply_bevel_modifier=False)

需要注意的是:脚本以if __name__ == "__main__"直接运行时(spaceship_generator.py),默认会先调用reset_scene()清场再生成单艘飞船。reset_scene()(spaceship_generator.py)的实现逻辑是:选中所有名称以Spaceship开头的对象并删除,随后清理所有无引用的材质与纹理——这就是 README 所说"默认会删除所有 Spaceship 前缀对象"的来源。若你想在已有飞船的场景中追加生成,README 建议删除或注释主函数中约第 735 行的reset_scene()调用;在当前仓库版本中,该调用位于__main__单船分支(spaceship_generator.py)与电影渲染分支(spaceship_generator.py)两处,注释掉对应行即可保留旧飞船。

八、进阶技巧:自定义纹理与调参心得

README 的 Tips and Tricks 一节提供了三条实战经验,全部在源码中得到印证:

  1. 关闭自动清场:见上文reset_scene()说明;
  2. 使用种子复现:generate_spaceship('michael')这类字符串种子即可稳定复现;
  3. 替换自己的纹理:因为使用全局立方体投影,你完全可以换上自制贴图。替换 textures/hull_normal.png 可改变表面凹凸细节,替换 textures/hull_lights_diffuse.png 可改变舷窗颜色布局,替换 textures/hull_lights_emit.png 可改变窗户的发光图案——只要文件名不变,无需改动任何代码。

此外generate_spaceship()还暴露了大量影响生成过程的参数(段数、对称性、倒角、材质开关等),README 鼓励"多试试它们"。结合参数语义,几个实用的调参方向是:

  • 想要修长战舰:拉高num_hull_segments_max,并关闭create_asymmetry_segments减少杂乱;
  • 想要重型炮舰:关闭allow_horizontal_symmetry并提高num_asymmetry_segments_max,侧面的炮塔面会更多;
  • 想要"骨架"预览:关闭assign_materials与apply_bevel_modifier,获得干净的低多边形线框造型。

九、极值参数:算法边界的可视化验证

README 用"Extreme examples"一节展示了极端取值下的算法行为——把船体段数与不对称段数推到极大值,观察算法如何"失控"地堆叠几何。这正是理解生成器本质的最佳实验:由于段数上限soft_max=16只是滑块建议,你可以输入更大的数值,让船体拉伸出超长脊柱、非对称结构疯狂外凸,直观看到extrude_face/scale_face迭代累积的效果。

这类实验对二次开发尤其有价值:它暴露了算法对极端输入的鲁棒性边界(例如细长面跳过规则 spaceship_generator.py 正是为了避免畸形面),也帮你理解每个参数对最终形态的贡献权重。

十、彩蛋:批量渲染"舰队展示影片"

README 未展开但源码完整保留的第二个运行模式:把主函数中的generate_single_spaceship改为False(spaceship_generator.py),脚本会进入电影渲染模式——每隔total_spaceship_duration = 1秒生成一艘新飞船,相机绕船旋转拍摄,逐帧渲染输出,从而自动产出"舰队巡礼"影片(spaceship_generator.py)。

该模式内置了一批可调设置:

变量默认值含义
output_path''输出目录,留空则使用脚本所在目录
total_movie_duration16(秒)影片总时长
total_spaceship_duration1(秒)每艘飞船的展示时长
yaw_rate/yaw_offset45/220(度/秒)相机的偏航角速度与起始角度
camera_pole_rate1相机俯仰摆动频率
camera_pole_pitch_min/max15/30(度)相机俯仰角上下限
camera_pole_length10相机与飞船的距离(极轴半径)
camera_refocus_object_every_frameFalse是否每帧对准飞船
fov/fps60(度)/30视场角与帧率
res_x/res_y1920/1080渲染分辨率

渲染帧输出到renders/<时间戳>/<时间戳>_<帧号>.png,场景中若存在名为 'Plane' 的对象,脚本还会自动把它垫到飞船底部当反光地面(spaceship_generator.py)。

十一、许可与致谢

项目以MIT License发布(见仓库根目录 LICENSE),由 Michael Davies 编写并维护;社区贡献者 @panzi 修复了 Bug、提供了正式 GUI 与构建脚本,@mjrthemes 参与修 Bug,@LendoK 完成了 Blender 2.80 移植。得益于 MIT 许可与单文件脚本架构,你完全可以把spaceship_generator.py嵌入自己的 Blender 工具链,或将细节生成器抽取为自定义节点逻辑,在其上构建属于你自己的程序化资产管线。

  • 3D建模
  • 图形学

【免费下载链接】SpaceshipGenerator

A Blender script to procedurally generate 3D spaceships

项目地址:https://gitcode.com/gh_mirrors/sp/SpaceshipGenerator
点击查看免费下载
上一篇:Argo Workflows 同步机制(Synchronization)完全指南:从本地锁到多控制器数据库锁
下一篇:TDengine 时序数据预测:Theta 算法模型实战指南(FORECAST 函数参数、示例与源码解析)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询