免模型文件:以代码构建3D世界的艺术-Vue3联合Three.js实现程序化资产生成实战

作者:袖梨 2026-05-27
探索3D世界的无限可能,通过Vue3与Three.js结合程序化生成技术,告别传统建模方式,实现高效动态构建。本文将详细介绍如何从零打造可交互的3D资产系统。 不写模型文件,用代码「捏」出 3D 世界:Vue3 + Three.js 程序化资产生成实战 本文对应开源仓库:qdcxj/three.js-3d-assets 基于原项目:boytchev/3d-assets 的 Vue 3 二次开发版本 效果预览 Demo 展示页(/demo)呈现16种程序化生成的3D资产,每张卡片展示一个模型,支持点击"重新生成"按钮创建随机变体。 前言:为什么不用 .glb? 传统3D开发流程通常采用Blender建模后导出glTF格式,再由Three.js加载。虽然可行,但存在以下痛点: 问题 程序化生成的解法 尺寸修改需重新建模 调整数值即可实时重建几何体 变体数量与文件量成正比 一套参数数据配合generate()方法支持无限变体 下载体积庞大 纯JS计算实现,代码仅KB级别 UI控件难以联动 参数即API,天然支持表单对接 程序化生成(Procedural Generation)的核心思想在于:通过参数化设计实现动态建模。 本项目(three.js-3d-assets)基于boytchev/3d-assets进行了Vue化改造,已实现16种常见物体(如杯子、桌子、衣柜等),支持滑块实时调参、随机生成和场景组合展示功能。 下面将从架构设计到源码实现,完整解析实现方法。 一、整体架构 ┌─────────────────────────────────────────────────────────┐ │ Vue 视图层 │ │ AllInOne.vue / Demo.vue │ │ · 下拉选择资产 · 参数面板 · 滑块实时刷新 │ └───────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────▼─────────────────────────────────┐ │ ThreeScene.vue + useThreeScene.js │ │ · Scene / Camera / Renderer / OrbitControls │ │ · addObject / removeObject / clearScene │ └───────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────▼─────────────────────────────────┐ │ src/assets/ 资产层 │ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │ │ │ mug.js │ │ table.js │ │ catalog.js │ │ │ │ plate.js │ │ wardrobe.js │ │ (分类注册表) │ │ │ └──────┬──────┘ └──────┬───────┘ └───────────────┘ │ │ └────────────────┴──────────────────────────────│ │ │ │ │ assets-utils.js (基类 + 自定义几何体) │ │ bin-packing.js (UV 图集打包) │ └─────────────────────────────────────────────────────────┘ 数据流(调参时发生了什么): 二、项目目录说明 src/ ├── assets/ # 程序化资产核心 │ ├── assets-utils.js # Asset 基类、LatheUVGeometry、RoundedBoxGeometry... │ ├── bin-packing.js # UV 矩形打包算法 │ ├── mug.js / plate.js ... # 每个物体一个模块 │ ├── procedural-kit.js # 【扩展】工厂函数,快速批量造物体 │ ├── catalog.js # 【扩展】分类目录(家具/兵器/交通...) │ └── index.js # 统一导出 ├── components/ │ └── ThreeScene.vue # 3D 画布封装 ├── composables/ │ └── useThreeScene.js # Three.js 生命周期管理 └── views/ ├── AllInOne.vue # 全场景 / 单物体展示 + 参数面板 └── Demo.vue # 分卡片 Demo 三、核心设计:每个物体都是一个 Class 所有资产继承自Asset基类(本质是THREE.Group): // assets-utils.js class Asset extends Group { // 从 paramData 自动提取默认值 static get defaults() { let result = {} for (const [key, param] of Object.entries(this.paramData)) { result[key] = param.default } return result } // 按 min/max/chance 随机生成一套参数 static random() { let result = {} for (const [key, param] of Object.entries(this.paramData)) { if (param.type != Boolean) { result[key] = random(param.min, param.max, param.prec) } if (param.type == Boolean) { result[key] = Math.random() < param.chance } } return result } } 3.1 标准

相关文章

精彩推荐