[特殊字符]The Omniscient Tome | 全知之书
《全知之书》是一个创新的Web交互项目,结合3D图形学与计算机视觉技术,实现了零接触的AI手势交互体验。用户通过摄像头手势即可在虚拟魔法图书馆中翻阅书籍获取随机神谕。项目采用Three.js构建3D书籍模型,通过程序化纹理动态生成独一无二的书籍封面和内页,并实现物理翻页动画。核心功能包括MediaPipe手势识别(单手浏览、双手开启、握拳重置)、Canvas动态纹理绘制中文书法内容,以及Unrea
项目地址:https://github.com/MoonPointer-Byte/AnswerBook/
🔮 前言
在 Web 交互日益同质化的今天,如何打破“鼠标点击”的传统范式?
最近我尝试将 3D 图形学 (Three.js) 与 计算机视觉 (Google MediaPipe) 结合,开发了一个极具沉浸感的互动项目——《全知之书 (The Omniscient Tome)》。
在这个项目中,用户无需触碰键盘鼠标,只需对着摄像头挥挥手,就能在虚空中浏览一座宏大的魔法图书馆,选中并翻阅古老的典籍,获取随机的命运神谕。
先看效果图:
隔空手势翻阅 3D 魔法书
✨ 核心功能与亮点
-
🧙♂️ 零接触 AI 交互:基于 MediaPipe 的手部骨骼追踪,识别单手(浏览)、双手(开启)、握拳(重置)三种手势。
-
📚 程序化纹理 (Procedural Textures):项目中所有的书籍封面、皮革纹理、烫金边框、内页文字,全部通过 Canvas API 动态生成,无需加载任何外部图片资源,不仅加载快,而且每一本书都是独一无二的。
-
📖 拟真物理翻页:摒弃简单的贴图替换,构建了包含封面、封底、书脊的完整 3D 结构,实现了绕书脊轴心的物理翻页动画。
-
🌟 电影级后处理:使用了 UnrealBloom (泛光) 滤镜,配合粒子系统和动态点光源,营造出神秘的魔法氛围。
🛠️ 技术栈
-
渲染引擎:Three.js (r160+)
-
AI 视觉:@mediapipe/hands
-
动画库:GSAP (GreenSock)
-
字体:Google Fonts (Cinzel Decorative, Ma Shan Zheng)
💻 核心实现原理解析
1. 3D 书籍的建模与“关节”设计
要实现书本自然的“翻开”效果,不能简单地旋转整个物体。我将书本拆分为三个部分,并建立父子层级:
-
Root (根节点): 控制整本书的位置和整体旋转。
-
Spine (书脊): 固定在 Root 上。
-
BackGroup (封底组): 包含封底和右侧书页,固定在 Root 上。
-
FrontGroup (封面组): 关键点! 包含封面和左侧书页。它的旋转轴心设置在书脊处。
codeJavaScript
// 简化的建模逻辑
const root = new THREE.Group();
// 封面组 (这是可以活动的关节)
const frontGroup = new THREE.Group();
// 将封面几何体向右偏移,使其旋转轴心位于左侧边缘(书脊处)
const frontCover = new THREE.Mesh(coverGeo, matCover);
frontCover.position.set(B_W/2, 0, P_T/2 + B_T/2);
frontGroup.add(frontCover);
// 初始状态:合上 (旋转 -PI)
frontGroup.rotation.y = -Math.PI;
root.add(frontGroup);
root.add(backGroup); // 封底是固定的
当触发“开启”状态时,使用 GSAP 将 frontGroup.rotation.y 从 -Math.PI (合上) 动画过渡到 0 (摊平),就实现了翻书效果。
2. Canvas 动态纹理与中文书法
为了让每一本书翻开时都有不同的“神谕”,并没有预先准备几十张图片,而是利用 CanvasTexture 实时绘制。
这里利用了 Canvas 的绘图能力来模拟羊皮纸质感和发光文字:
codeJavaScript
function drawInnerPage(canvas, text) {
const ctx = canvas.getContext('2d');
const w = canvas.width, h = canvas.height;
// 1. 绘制发光底色 (配合 Bloom 滤镜)
ctx.fillStyle = "#ffffff";
ctx.fillRect(0,0,w,h);
// 2. 绘制古风中文文字
if (text) {
ctx.fillStyle = "#221100"; // 深墨色
ctx.font = "300px 'Ma Shan Zheng', cursive"; // 书法字体
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(text, w/2, h/2);
}
}
// 在翻书时动态更新纹理
const pageTex = book.userData.pageMat.map;
drawInnerPage(pageTex.image, "机缘");
pageTex.needsUpdate = true; // 告诉 Three.js 纹理已更新
3. MediaPipe 手势状态机
交互逻辑使用了一个简单的状态机来管理,防止手势冲突。
-
IDLE (待机): 寻找手部信号。
-
MOVE (浏览): 单手张开。映射手掌 X 轴坐标到 Scroll 速度。
-
CHARGING (蓄力): 双手张开。计算蓄力进度条,触发 Bloom 增强。
-
REVEALED (揭晓): 书籍打开状态。
-
SHUFFLE (重置): 检测到握拳(Fist),拥有最高优先级,强制重置所有状态。
codeJavaScript
// 手势识别核心逻辑
if (fistHands > 0) {
input.mode = 'SHUFFLE'; // 握拳优先级最高
} else if (openHands === 2) {
input.mode = 'ACTIVATE'; // 双手开启
} else if (openHands === 1) {
input.mode = 'MOVE'; // 单手移动
}
// 状态机处理
if (input.mode === 'SHUFFLE') {
resetGame();
} else if (input.mode === 'MOVE') {
// 平滑滚动逻辑
scrollTarget -= (input.x - 0.5) * speed;
}
🎨 视觉美化:Bloom 与 粒子
为了达到“魔法”效果,后处理(Post-processing)是必不可少的。
使用了 UnrealBloomPass,但调整了 threshold (阈值),确保只有书本的金色边框、魔法阵和翻开后的白纸会发光,而背景保持深邃的黑。
同时,配合一个简单的粒子系统(Explosion Particles),在书本翻开的瞬间释放粒子,增加冲击力。
如何在本地运行?
-
克隆项目到本地。
-
由于涉及摄像头权限和纹理加载,不能直接双击 HTML 打开。
-
推荐使用 VS Code 安装 Live Server 插件,右键 Open with Live Server。
-
或者使用 Node.js: npx http-server。
更多推荐



所有评论(0)