我的3D和Three.js入门学习(2)
3D 零基础入门 · 第 2 章:坐标系——顶点站在哪儿
第 1 章我们知道了:模型 = 一堆顶点 + 一堆三角形。
这一章回答:顶点的坐标 (x, y, z) 到底是什么意思?模型放进场景里,怎么知道"脸朝哪、脚站哪、多大"?
2.1 三维坐标:给空间画一张格子纸
想想初中数学的坐标系:一条横轴 x,一条竖轴 y,一个点用 (x, y) 表示。3D 只是多了一条轴:
| 轴 | 方向 | 类比 |
|---|---|---|
| X | 左右 | 东西方向 |
| Y | 上下 | 高度 |
| Z | 前后 | 南北方向 |
一个顶点 (1, 2, 3) 的意思就是:沿 X 走 1,沿 Y 走 2,沿 Z 走 3,到达的那个点。
想象你在房间里:X 是左右墙,Y 是屋顶方向,Z 是你面对的方向。任何东西的位置,都能用"往左多少、往上多少、往前多少"描述。
在 Three.js 里代表了"上下左右前后"的标尺,叫 AxesHelper(坐标轴),红绿蓝三根线分别就是 X、Y、Z。
2.2 世界有两种"上下左右":坐标系的坑(必看)
同一个模型,在不同软件里打开,有可能头朝上也可能横躺着——因为大家约定的"Y 是上还是 Z 是上"不一样:
| 软件 | 约定 | 说明 |
|---|---|---|
| Blender | Z 轴朝上 | 建模时的习惯 |
| Three.js / GLTF / 游戏 | Y 轴朝上 | 我们项目用的就是它 |
| Unity | Y 轴朝上(但左手系) | 老坑,后面会提 |
我们项目以"Y 朝上"为准:脚在低处,头在高处,人物正面朝 Z 轴方向。
这就好比:出门导航用的是"上北下南",但你同桌画的流程图是"上东下西"——同一个世界,图纸不同,要看清楚用的是哪张图纸。
好在 Blender 导出成 GLTF 时,会自动把 Z-up 转成 Y-up(第 1 章书稿提过),所以大多数时候你感觉不到这个坑。但写代码手算坐标时,永远要问一句:现在是哪条轴朝上?
2.3 模型的"三件套":位置 Position、旋转 Rotation、缩放 Scale
一个模型放进 3D 场景,除了"顶点在哪",还需要知道它自己怎么摆。Three.js 里每个物体都有三个属性,合称 TRS:
| 属性 | 英文 | 一句话 | 类比 |
|---|---|---|---|
| 位置 | Position | 物体中心在世界的哪个点 (x, y, z) |
你站在房间哪 |
| 旋转 | Rotation | 物体朝哪个方向转 (x, y, z),单位是弧度 |
你面朝哪、低头没 |
| 缩放 | Scale | 物体多大 (x, y, z) 倍数 |
你被放大镜照了多少倍 |
mesh.position.set(0, 1, 0); // 站到 1 米高的地方
mesh.rotation.y = Math.PI / 2; // 绕 Y 轴(垂直轴)转 90°
mesh.scale.set(1.5, 1.5, 1.5); // 整体放大 1.5 倍
记住一个顺序:先缩放 → 再旋转 → 再位移。Three.js 渲染时就是按这个顺序组合的(数学上叫"变换矩阵",第 4 章简提一句,现在不用深究)。
旋转的方向:Three.js 是右手系. 想象你右手握拳、大拇指朝上(Y 轴),四指从 X 往 Z 弯曲的方向,就是正旋转方向。
类比:拧水瓶盖。顺时针拧紧、逆时针拧松?在 Y-up 世界从上往下看,逆时针是正方向。不需要死记,demo 里转一转就有感觉了。
2.4 父子关系:模型不是孤立的
第 1 章我们说过,人物身体的各个部位(头、手、剑)不是飘在空中的——它们挂在一起。
Three.js 里用"父子"表示:子物体的坐标是相对父物体的。
root(父)在 (0, 1, 0),sword(子)position 是 (0.5, 0, 0),
那么剑的世界坐标 = 父位置 + 子相对位置 = (0.5, 1, 0)。
类比:你的手机放在桌上,桌子的位置变了,手机跟着变;手机自己也有个位置(在桌子的哪个角落)。
这极其重要——本期项目里,武器挂在手上的骨骼上,手动了剑就跟着动,就是这个"父子"机制在起作用(第 6 章展开)。
scene.add(root); // 根
root.add(sword); // 剑挂在 root 下
2.5 对照我们项目的真实数据
打开 viz/anim-idles.json,骨架(rig)里每根骨骼都有 t、q、s 三个字段——就是 TRS!
{"name":"Back","parent":3,"t":[0,0,0],
"q":[-0.018967799921477443,0.014887063473919384,0.003164132685052772,0.9997042493469767],
"s":[1,1,1]}
| 字段 | 含义(对应 TRS) |
|---|---|
t |
Position(位移)——这根骨头相对它爸爸往哪挪 |
q |
四元数表示的 Rotation(旋转)——四元数先不用懂,知道它是"旋转的另一种写法、不会卡死"就够了 |
s |
Scale(缩放) |
parent |
它挂在几号骨骼下面(父子关系!) |
所以:你已经能读懂真实项目的骨架数据了。 第 6 章我们会亲眼看到这些数字怎么让模型动起来。
2.6 动手做:TRS 三件套转起来
[!demo] demos/demo02-transform.html | 坐标系与 TRS
红 X · 绿 Y · 蓝 Z 三条轴;用面板上的滑块拖动 Position / Rotation / Scale,看物体在空间里怎么"移动、旋转、缩放"。
你会看到一个立方体 + 红绿蓝三根坐标轴。拖动三个滑块:
- Position:立方体沿着轴滑动;
- Rotation:立方体旋转(试试绕 X 转 90° 是什么样);
- Scale:立方体变大变小。
再把立方体绕着 Y 轴慢慢转,观察它是逆时针方向转的(右手系)。
做完这步,你对"TRS"就有了肌肉记忆。下一章我们回答:有了形状和位置,模型为什么是黑的? —— 灯光、材质、相机。
2.7 本章小结
- 顶点坐标 = 房间里的"往左多少、往上多少、往前多少"(x, y, z)
- 坐标系有种族差异:Blender 是 Z-up、Three.js/GLTF 是 Y-up
- 每个物体有 TRS 三件套:Position / Rotation(弧度,右手系)/ Scale
- 物体可以挂父子,子坐标是相对的——武器的"跟手"全靠它
- 真实项目
anim-idles.json里每根骨骼的t/q/s就是 TRS,你已能读懂
下一章 → 材质 / 灯光 / 相机
配套 demo:
demos/demo02-transform.html
相关源码位置:viz3d.js的animate()(每帧更新骨骼 TRS)与initRig()(建 28 根骨骼,第 339 行附近)。
- 点赞
- 收藏
- 关注作者
评论(0)