背景
最近有个需求,需要在项目中插入一个 3D 人物。为了能够在需求出来之前,从前端技术角度初步排除下有没有坑,所以准备尝试做一下简单的技术调研。
这里跟大家分享下我跟我的 AI 同事们合作搞定这件事的过程,希望可以给大家提供一些参考。
目录
- 需求分析
- 技术方案
- 核心实现
- 效果展示
需求分析
通过仔细分析了项目的实际需求后,抽象出了核心功能:在网页中渲染一个 3D 人物模型。
将需求拆分成两个步骤:
- 创建一个可以在网页中渲染的 3D 人物模型
- 在网页中渲染这个 3D 模型
简化后:
- 获取 3D 人物模型
- 渲染 3D 人物模型
技术方案
明确了需求后,接下来就该我的 AI 同事们上场了。这里我对它们做了简单的分工:
- 通用 LLM 大模型部门的同事:生成一段可以创建人物图片的提示词
- 文生图大模型部门的同事:生成一张人物图片
- 图片生成模型部门的同事:生成一个 3D 任务模型
- 代码生成部门的同事:根据我的需要,生成能够直接渲染 3D 模型的代码
听说不会偷懒的程序员,不是好的厨子。
所以我准备不写一行代码,来实现整个需求。完全信任我的同事们。
- 提示词生成:使用 Kimi
- 文生图:使用 Vega AI
- 图生 3D 模型:使用 ReadyPlayer.Me
- 代码生成助手:使用 MarsCode
tips:本人不为任何 AI 产品做广告,此处只是为了做演示,大家可以根据自身情况选择合适的 AI 产品。
核心实现
提示词生成(用时约为1分钟)
之所以需要借助 AI 生成“文生图”的提示词,是因为我不太相信自己提示词编写的水平,因此不如直接交给我的同事来搞定,而我只需要说出需求即可。
我跟同事的对话如下:
太长了,继续精简:
精简后的提示词:
生成一位30岁左右亚洲女性穿正装的3D渲染全身像。要求:面容精致,气质优雅。着装包括深色西装外套、白色衬衫、直筒西裤,配黑色尖头高跟鞋。背景为简约办公室,模特自然站立,微笑。图像高清,适合商业用途。
搞定,去找下一位同事吧。
人物图片渲染(用时约为2分钟)
因为我对人物的形象没有太多细节要求,因此只要不太离谱,越快生成越好。
这里选择一个自己看上去比较还不错的图片,下载到本地。如果你不满意,可以微调,甚至相同的文案,再次生成。
搞定,继续找下一位同事。
3D 模型生成(用时约2分钟)
进入 ReadyPlayer.Me 网站,选择我们刚才下载的图片。
上传文件。
接着下一步即可。
最终我们可以复制生成的这个模型的 GLB 地址:models.readyplayer.me/66f6497420c…
需要注意的是:
- 这个过程可能会提示一些报错,建议无痕模式访问。
- 生成的模型并不是完全跟我们的图片一样,但作为测试,基本够用。
接着我们可以拿着模型,去找我们的“开发同学”。
代码生成(用时约5分钟)
打开 MarsCode,创建一个前端页面项目。
向它说明你的来意:
我想实现通过js加载glb模型,在web页面中渲染3D人物,请给我一个完整的代码示例,而我只需要传入特定的 glb 模型地址即可
把代码放到左侧的 html 文件中。
把我们上一个步骤复制的 glb 地址,替换path_to_your_model.glb即可。点击运行。
此时,发现右侧预览页面,什么也没有,接下来我们该请教同事帮我们解决这个问题。因为预览页面无法看到实际的报错,我们可以点击预览或直接复制预览地址在新的浏览器 Tab 中打开,可以看到相关报错信息。
定位到问题,那么就继续请教我们的同事,看看它有什么好的建议。
再探,再报。在我一步一步解决了引入问题后,发现依然无法渲染。
最终。。。。我放弃了使用 MarsCode,因为它让我自己排查错误,而不是再帮我生成一段代码。
为了不耽误时间,我决定用 ChatGPT 来帮我救场,最终它给我了全新的代码,并正常渲染了页面,当然我跟 ChatGPT 更多纠缠的是 Three.js 的引入问题,而非逻辑问题。
这里我把最终可以渲染的完整代码贴出来,感兴趣的同学可以本地跑一下试试。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GLB 3D Model Viewer</title>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style>
</head>
<body>
<!-- 使用 import map 来简化导入路径 -->
<script type="importmap">
{
"imports": {
"three": "./libs/three.module.min.js"
}
}
</script>
<script type="module">
// 导入 three.js 和 GLTFLoader 模块
import * as THREE from "three";
import { GLTFLoader } from "./libs/GLTFLoader.js";
let scene, camera, renderer, model;
function init() {
// 创建场景
scene = new THREE.Scene();
scene.background = new THREE.Color(0xdddddd);
// 创建摄像机
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 5;
// 创建渲染器
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// 加载并渲染 GLB 模型
const loader = new GLTFLoader();
const glbUrl =
"https://models.readyplayer.me/66f2af93e85af47110f16079.glb"; // 替换为你的 GLB 模型 URL
loader.load(
glbUrl,
function (gltf) {
model = gltf.scene;
scene.add(model);
animate();
},
undefined,
function (error) {
console.error("An error occurred:", error);
}
);
// 响应窗口大小调整
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
// 旋转模型以展示效果
if (model) {
model.rotation.y += 0.01;
}
renderer.render(scene, camera);
}
// 初始化场景
init();
</script>
</body>
</html>
需要注意的是:
- 上述代码中,我是将 Three.js 的代码下载到了本地,因此注意替换上面的引入路径
- 为了方便对比,我也把 MarsCode 生成的代码放到本地运行,依然无法正常渲染。不过本文的核心还是为了以实现最初的目标为主,因此没有过多的再花时间在 MarsCode 上调优。
效果展示
在多个同事的努力下,我们最终可以看到如下的效果。
至此,我们完成了我们想要的结果,当然你也可以基于此让 AI 帮你优化出更好的效果。
杂谈
- 本文不对使用过程中的任何工具做测评,因此如果你想把某个环节中的效果打磨的更好,可以根据你对 AI 工具的理解,做相关平替。
- 经过上面的案例,你会发现,在 AI 时代,编码能力变得越来越不重要了。重要的是如何梳理出一套可以让 AI 帮你编码的业务拆解能力和需求描述能力。拥有了这两个能力,你可以知道如此多的 AI 工具,哪一个能帮你解决不同的问题,以及如何跟 AI 对话,让它真正的帮你写出你想要的代码。
- 在使用 AI 工具的过程中,我越来越体会到高质量的训练数据对大模型的重要性。很多时候,大模型的答案是有时效性的。也可以这么理解,现阶段的大模型能够回答你的问题,更多的是这个行业或这个世界已经存在的方案。如果这些方案还不存在,那么大模型更多的是猜测可能的结果,而达不到精准的结果。
- 深度的使用过 AI ,才不会畏惧 AI,我们因此才能更从容的接受 AI。
最后
其实内心稍微纠结了一下,要不要让这篇文章参加 “码” 上双节,共话精彩 ——豆包MarsCode 放“码”过来!创意征文活动,毕竟在使用 MarsCode 生成代码的环节,效果并不理想。
但是反过来想了下,无论任何一个大模型,都需要有一个不断打磨的过程,如果因为挂上了这个话题,能让负责 MarsCode 的同学更快速的看到一个特殊的 Case,未尝不是一件好事,希望有助于 MarsCode 底层大模型不断优化。
所以,也就释然了。也许下一次再参加活动时,MarsCode已经变得更强了。