简介:本文讲解如何用大模型把自然语言需求转化为可交互三维网页原型,覆盖 Three.js 选型、提示词设计、最小可运行代码、折叠与拆解交互、调试验证、成本控制。读者可掌握从零搭建、快速验证和稳定迭代的方法,在有限预算内产出可演示、可维护的技术作品。
本教程要解决的核心问题是:如何让开发者利用大模型的能力,把一段自然语言描述快速转化为可以在网页中运行的三维交互原型。
这里的目标不是简单生成一张概念图,也不是只输出一段无法运行的示例代码,而是完成一个具备以下特征的最小可用原型:
从常见三维网页原型实践来看,大模型参与的三维网页创作通常可以归纳为三类方向:
本教程将围绕这些典型场景,给出一条可复用的制作路径。
本教程适合以下读者:
适合使用本教程的场景包括:
大模型驱动的网页三维原型适合验证创意、交互和视觉方向,但不适合直接替代以下生产场景:
当项目出现这些需求时,通常需要专业三维引擎、离线渲染管线、物理引擎、服务端仿真环境或专业工程团队深度参与。
在开始制作之前,需要完成几类准备工作。准备工作越充分,后续生成结果越稳定。
建议准备以下基础条件:
npx serve . 或 VS Code Live Server;这里强调“代码管理”并不是为了复杂化流程,而是因为大模型生成结果往往具有不确定性。只有把每一次生成、修改、回滚都记录下来,才能稳定复盘问题。
生成三维网页原型时,需要明确使用哪个渲染库。常见选择有两类:
Three.js 生态成熟、示例多,适合网页三维原型、产品展示和轻量交互。
推荐版本约束:
0.160.0;r150 以上版本;latest,因为大模型生成的代码可能依赖旧版 API。安装方式:
npm init -ynpm install three@0.160.0
如果使用 CDN 或 importmap 引入,可以在 index.html 中配置:
<script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.160.0/build/three.module.js","three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"}}</script>
加载 glTF 模型时,可以使用 GLTFLoader:
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
Babylon.js 自带较完整的场景、材质、动画和加载体系,适合需要更完整三维工程能力的原型。
推荐安装方式:
npm install @babylonjs/core @babylonjs/loaders
常见入口写法:
import { Engine } from '@babylonjs/core/Engines/engine';import { Scene } from '@babylonjs/core/scene';
三维网页原型通常涉及以下资产:
如果团队没有现成资产,建议优先使用低模、程序化几何体和简洁材质。原因是:大模型生成代码时,复杂资产容易带来加载失败、性能下降和调试困难。
推荐模型格式:
.glb:二进制单文件,便于传输;.gltf:文本格式,便于人工查看节点结构;一个最小可运行三维网页通常只需要以下文件:
index.htmlmain.js
其中:
index.html 负责页面入口、画布容器、按钮和脚本引入;main.js 负责场景初始化、摄像机、光照、渲染循环和交互事件。后续可以拆分为:
index.htmlmain.jsscene.jscamera.jslighting.jsassets.jsinteraction.jsstate.jsui.js
原型阶段先保持小范围可运行,再逐步拆分模块,会更稳定。
开发者需要理解几个通用概念:
这些概念并不需要全部深入,但在排查问题时会反复用到。
一个完整流程可以分为六个阶段:
这条流程的关键点在于:不要让模型一次性完成所有事情。更稳妥的方式是“分步生成、逐步验证”。
在调用大模型之前,先把原型目标写成一份清单,至少包括:
例如,一个可折叠设备演示原型可以定义为:
如果直接把一句模糊需求交给模型,例如“做一个很酷的三维页面”,模型很难判断优先级。它可能生成大量细节,却无法形成稳定交互。
先写清目标,相当于给模型提供验收标准。这样可以减少无效生成,也方便后续判断结果是否达标。
结构化提示词是指把需求拆成固定字段,让模型更容易理解。常见字段包括:
目标:原型类型:场景元素:交互列表:视觉风格:输出文件结构:负向约束:禁止事项:输出要求:约束条件:验收检查项:
以下是一个通用示例:
目标:制作一个可折叠设备的三维交互网页原型。原型类型:产品概念展示页。场景元素:- 一个位于页面中央的折叠设备;- 设备包含上盖、下盖、屏幕区域;- 背景为浅灰色,带柔和阴影。交互列表:- 页面加载后,设备处于合拢状态;- 点击“展开”按钮,设备上盖旋转打开;- 点击“合拢”按钮,设备上盖旋转关闭;- 展开过程中,屏幕内容亮度逐渐提升。视觉风格:简洁、科技感、干净、适合产品发布。输出文件结构:- index.html- main.js- scene.js- interaction.js负向约束:- 不要引入未定义的第三方插件;- 不要使用大型视频资源;- 不要生成后端服务;- 不要输出完整压缩混淆代码;- 不要使用超过 2 秒的动画;- 不要改变已有文件名;- 不要假设页面中已经存在未知全局变量。禁止事项:- 禁止使用版权图片;- 禁止使用不可访问的远程资源;- 禁止在代码中调用不存在的接口;- 禁止将按钮直接绑定到三维对象变换逻辑,应通过状态或统一交互入口处理。输出要求:- 使用网页脚本实现三维场景;- 将场景、交互、状态管理拆分到不同模块;- 提供可运行的代码结构;- 使用程序化几何体作为占位模型;- 动画时长控制在 1.5 秒以内;- 代码中避免未定义的函数和接口。约束条件:- 优先使用 Three.js 0.160.0;- 使用 glTF 2.0 作为后续模型接入格式;- 首屏资源体积控制在 10MB 以内;- 页面加载后应可直接点击按钮交互。验收检查项:- 页面可以加载;- 展开与合拢状态正确切换;- 控制台无未捕获错误;- 交互按钮可以重复点击;- 动画过程不出现角度跳变;- 页面没有空白画布。
结构化提示词有三个好处:
在目标明确后,让模型先生成代码骨架,而不是直接生成完整实现。
一个常见的三维网页原型骨架包括:
如果让模型一次性生成全部代码,容易出现以下问题:
先生成骨架,再逐个模块填充,可以显著降低复杂度。
下面给出一个可以直接打开的三维交互网页原型入口。
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>折叠设备三维交互原型</title><style>body { margin: 0; overflow: hidden; }#app { width: 100vw; height: 100vh; }#ui {position: fixed;left: 16px;top: 16px;z-index: 10;}button {padding: 10px 16px;font-size: 14px;cursor: pointer;}</style></head><body><div id="app"></div><div id="ui"><button id="toggleButton">展开 / 合拢</button></div><script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.160.0/build/three.module.js"}}</script><script type="module" src="./main.js"></script></body></html>
import * as THREE from 'three';const container = document.querySelector('#app');const toggleButton = document.querySelector('#toggleButton');const scene = new THREE.Scene();scene.background = new THREE.Color(0xf5f5f5);const camera = new THREE.PerspectiveCamera(50,window.innerWidth / window.innerHeight,0.1,100);camera.position.set(3, 3, 5);camera.lookAt(0, 0, 0);const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);renderer.setPixelRatio(window.devicePixelRatio);container.appendChild(renderer.domElement);const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);scene.add(ambientLight);const directionLight = new THREE.DirectionalLight(0xffffff, 1.2);directionLight.position.set(5, 8, 5);scene.add(directionLight);const device = new THREE.Group();const lowerBody = new THREE.Mesh(new THREE.BoxGeometry(2, 0.2, 1.4),new THREE.MeshStandardMaterial({ color: 0x334155 }));lowerBody.position.y = -0.1;device.add(lowerBody);const upperBody = new THREE.Mesh(new THREE.BoxGeometry(2, 0.2, 1.4),new THREE.MeshStandardMaterial({ color: 0x64748b }));upperBody.position.set(0, 0.1, -0.7);device.add(upperBody);const screen = new THREE.Mesh(new THREE.BoxGeometry(1.7, 0.03, 1.1),new THREE.MeshStandardMaterial({ color: 0x0ea5e9 }));screen.position.set(0, -0.25, 0);device.add(screen);scene.add(device);let isOpen = false;let currentAngle = 0;function getTargetAngle() {return isOpen ? -Math.PI * 0.85 : 0;}toggleButton.addEventListener('click', () => {isOpen = !isOpen;});window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);});const clock = new THREE.Clock();function animate() {requestAnimationFrame(animate);const delta = clock.getDelta();const targetAngle = getTargetAngle();currentAngle += (targetAngle - currentAngle) * Math.min(1, delta * 6);upperBody.rotation.x = currentAngle;renderer.render(scene, camera);}animate();
这个示例包含了一个可运行的最小结构:
后续可以在该骨架上继续增加资产加载、状态管理、爆炸视图、视角跟随等模块。
场景是原型的第一层基础。建议从简单元素开始:
如果目标是开放世界风格场景,可以先简化成:
不需要一开始就生成完整城市。原型阶段重点是验证“能否形成开放世界氛围”。
如果原型需要使用三维模型,建议统一以下规范:
例如,一个折叠设备可以拆成:
DeviceLowerBodyUpperBodyScreenHinge
这样在后续实现折叠动画时,模型可以准确找到上盖、屏幕和铰链。
三维原型中最常见的问题不是“不够漂亮”,而是“结构混乱导致无法交互”。
如果对象命名不清,模型生成代码时可能错误引用节点;如果层级过深,动画控制会变得困难;如果贴图过大,加载时间会明显增加。
对于机械手、设备内部结构等复杂对象,可以采用“爆炸视图”思路:
通用伪代码:
onExplodeClick() {parts.forEach(part => {part.targetPosition = part.initialPosition.add(part.explodeDirection.multiply(distance));});}onResetClick() {parts.forEach(part => {part.targetPosition = part.initialPosition;});}updateAnimations(deltaTime) {parts.forEach(part => {part.position.lerp(part.targetPosition, easingFactor);});}
折叠设备的交互核心是状态切换。常见状态包括:
推荐使用状态机方式管理:
enum DeviceState {CLOSED,OPENING,OPEN,CLOSING}
状态变化示例:
if (state == CLOSED && clickExpand) {state = OPENING;}if (state == OPENING && progress >= 1) {state = OPEN;}if (state == OPEN && clickFold) {state = CLOSING;}if (state == CLOSING && progress <= 0) {state = CLOSED;}
如果只用按钮直接修改旋转角度,容易出现:
状态机可以把“用户意图”和“动画过程”分开,让原型更稳定。
拆解交互的关键是“每个零件都有目标位置”。
实现时建议:
如果制作开放世界风格场景,可以让摄像机跟随一个目标对象:
target = mainObject;desiredCameraPosition = target.position.add(offset);camera.position.lerp(desiredCameraPosition, followSpeed);lookTarget = target.position.add(lookOffset);camera.lookAt(lookTarget);
这里的关键是:
布料效果可以通过简化物理实现:
通用思路:
for each vertex in clothMesh {vertex.z = sin(time + vertex.x) * amplitude;}
这样不会达到真实布料仿真,但可以形成“飘动”的视觉效果。
如果需要制作发布短片,可以先让模型生成分镜脚本,再生成对应的动画时间线:
原型阶段不需要完整视频,可以先生成网页动画,再通过录屏方式输出短片。
大模型适合“局部修改”,不适合“无限重写”。建议按以下方式迭代:
当前目标:修复折叠动画在展开过程中卡顿的问题。现象:点击展开按钮后,设备先跳转到中间角度,然后继续播放动画。相关代码:{粘贴相关模块}预期结果:设备从当前角度平滑过渡到目标角度,不出现跳变。约束条件:- 只修改状态管理模块;- 不改变页面结构;- 不引入新的外部依赖。
如果只说“页面有 bug”,模型很难定位问题。提供以下信息会显著提高修复质量:
当原型越来越大时,不建议把所有代码一次性塞给模型。可以采用以下策略:
大模型生成结果会受调用方式影响。虽然不同服务的参数名称可能不同,但通用配置逻辑可以总结如下。
常见参数包括 temperature 和 top_p。
temperature 设置为 0.2 到 0.5,以提高稳定性;temperature 设置为 0.7 到 1.0;原因:高随机性适合发散创意,但会降低代码确定性。
常见参数是 max_tokens 或类似输出长度参数。
原因:过长输出容易导致上下文混乱,也增加令牌消耗。
如果大模型服务支持外部上下文、文档检索或代码检索,可以配置为:
这样做的目的是减少模型凭空生成不存在的接口。
建议在调用前设置:
如果项目运行在云环境中,可以通过云服务控制台查看调用量、日志和告警,避免意外消耗。
下面给出一个通用流程示意,不依赖任何具体工具或平台。
制作一个开放世界风格的网页原型:- 有道路、车辆、人物;- 摄像机跟随主角色;- 支持前后左右移动;- 支持镜头切换;- 画面简洁,使用低模风格;- 第一版只需要完成基础移动和视角跟随。
可以要求模型输出如下结构:
scene.jscamera.jsplayer.jsvehicle.jsinput.jsui.js
initWorld() {createRoad();createBuildings();createPlayer();createVehicles();createCameraFollow();bindKeyboardInput();}update(deltaTime) {updatePlayerMovement(deltaTime);updateVehicles(deltaTime);updateCamera(deltaTime);render();}onKeyDown(key) {if (key == "forward") player.moveForward();if (key == "backward") player.moveBackward();if (key == "left") player.rotateLeft();if (key == "right") player.rotateRight();}
- 页面是否能正常加载;- 主角色是否可见;- 道路和车辆是否可见;- 键盘操作是否生效;- 摄像机是否跟随;- 控制台是否有报错;- 帧率是否可接受;- 生成代码是否包含未定义函数。
原型完成后,需要从功能、性能、体验、成本四个方面验证。
检查以下内容:
可量化口径示例:
关注以下指标:
可量化口径示例:
50 FPS 到 60 FPS;30 FPS 左右;3 秒 内;10MB 以内;从用户视角观察:
记录:
成本验证不是为了追求最低价,而是为了判断该方案是否适合继续扩展。
可能原因:
排查思路:
可能原因:
排查思路:
可能原因:
排查思路:
可能原因:
优化思路:
可能原因:
解决思路:
可能原因:
优化思路:
如果团队多人参与,可以约定:
本教程围绕“如何用大模型制作可交互三维网页原型”展开,核心结论是:大模型可以显著提升原型阶段的效率,但前提是把任务拆解清楚,把验收标准写明白,把生成过程模块化。
需要强调的是,大模型不保证一次生成成功。开发者仍然需要进行人工验证、逐模块回归、错误修复和性能检查。
从常见原型场景可以抽象出三条经验:
短片段比完整项目更容易控制
一支发布短片、一个折叠交互、一个局部拆解,通常比一上来就制作完整开放世界更容易成功。
结构化提示词比自然语言更重要
把目标、资产、交互、约束、验收标准写清楚,可以显著减少模型臆造和返工。
成本控制要靠流程,而不是靠感觉
记录令牌消耗、生成次数、修复时间和资产体积,才能判断该方案是否值得继续投入。
对于团队来说,最有价值的不是“让模型生成一次炫酷页面”,而是建立一套可重复、可验证、可扩展的生产方法。后续可以继续关注三维资产自动生成、交互动效模板化、网页原型自动化测试、成本监控看板、多模态输入驱动的场景搭建,以及企业级原型资产库建设。