想展示3D模型,网页上咋整?元素这波操作能行不?

2,765字
12–18 分钟
in

摘要:最近刷到Safari技术预览版悄悄支持了个叫的新标签,专门用来在网页里放3D模型。这东西就像

目录

是个啥

3D模型在网页上以前都是硬骨头,得靠canvas和一堆JS脚本才能勉强搞出来。现在冒出来个元素,想学那样潇洒,一个标签就把立体物件怼上去。这玩意儿最初是沉浸式网页社区工作组捣鼓的提案,苹果在自家的AR Quick Look功能上先试了水。简单说,就是给网页塞3D内容用的,支持的文件格式主要是.usdz(苹果家的AR格式)和.glb(3D模型的通用二进制格式)。好比

上手整个3D模型

要玩转,得先有个模型文件。网上可以找免费的.glb示例,比如谷歌的“AR恐龙”或者微软的“3D机器人”。准备两个格式最保险:.usdz给苹果设备,.glb给其他浏览器。

基础写法

直接在HTML里怼上这段代码:

<model style="width: 400px; height: 300px;">
  <source src="dinosaur.usdz" type="model/vnd.usdz+zip">
  <source src="dinosaur.glb" type="model/gltf-binary">
  这破浏览器不支持3D模型,换个新点的版本吧。
</model>

这里style控制显示框大小,里面的文字是后备内容,当浏览器不认识的时候就会显示出来。第一个是.usdz,第二个是.glb,浏览器会从上往下挑一个它能吃的格式。

加个控制器让模型转起来

提案里还提到了controls属性,加上之后就能用鼠标拖拽旋转、缩放模型,就像逛淘宝3D商品图那样:

<model src="robot.glb" controls autoplay loop style="width: 100%; height: 500px;">
</model>

autoplay让模型一加载完就自动播放动画(如果模型本身带动画),loop让动画循环播放。目前这些属性还在草案阶段,Safari TP版可能只支持最基础的src和。

实际踩坑时发现,模型文件不能太大,超过10MB容易卡死。可以用gltf-pipeline这类工具压缩.glb,瘦身一半不成问题。另外模型的面数别整太高,手机上看三万面以内比较丝滑。

浏览器不认咋办

现在还是试验田里的菜,主流浏览器没几个支持的。这时候得搬出备胎方案,让旧浏览器也能看到3D内容。有三个路子:

方案适用场景上手难度
模型截图糊弄静态展示
全功能交互
three.js手撸极致定制

方案A:用组件

谷歌整了个Web组件叫,不用等标准化就能用。先加载它的JS库:

<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js"></script>
<model-viewer src="dinosaur.glb" alt="一只3D恐龙" auto-rotate camera-controls style="width: 600px; height: 400px;">
</model-viewer>

auto-rotate让模型自己转圈,camera-controls允许拖拽视角。这个组件已经稳定运行好几年,苹果、谷歌都在用。跟相比,它需要额外加载JS,但兼容性好到IE都哭。

方案B:降级成静态图片

如果不想折腾JS,直接截几张模型不同角度的图,用元素搞响应式:

<picture>
  <source srcset="dinosaur.webp" type="image/webp">
  <img src="dinosaur.jpg" alt="恐龙3D模型示意图">
</picture>

虽然不能交互,但至少能让所有人看到模型长啥样。这种“假3D”在电商详情页里很常见,点一下图片才加载真正的3D查看器。

实操步骤(小白版)

想在自己网页里放个能转的3D模型,按下面步骤整:

  1. 下载一个.glb模型文件,可以去Sketchfab搜免费下载的,挑个低于5MB的。
  2. 把文件放到网站目录下,比如/models/example.glb
  3. 复制的CDN链接到HTML的里面。
  4. 在页面里写<model-viewer src="/models/example.glb" camera-controls style="width:100%; height:500px"></model-viewer>
  5. 用本地服务器打开测试(直接双击HTML文件可能因为跨域问题加载不了)。
  6. 手机上也扫一遍,看看触摸旋转好不好使。

踩坑提醒:模型贴图丢失经常是因为.glb文件引用了外部纹理图片,最好用glTF格式把贴图打包进去。还有,模型中心点不在物体中间时,旋转起来会鬼畜,得用Blender打开模型,把原点设置到几何中心再导出。另外,Safari上.usdz文件必须走HTTPS,否则直接罢工。

文件格式那些破事

.usdz是苹果搞的压缩包格式,里面能塞3D模型、纹理、动画,iOS上一键AR预览。.glb则是Khronos Group的通用格式,安卓和Windows都能打。建议两个都提供,让或自己选:

<model-viewer 
  src="model.glb" 
  ios-src="model.usdz"
  camera-controls>
</model-viewer>

model-viewer组件有个ios-src属性专门伺候苹果。如果只用,就像第一个例子那样用标签按顺序写。

有些老工程还用的.obj或.fbx,这俩别直接往里塞,得用命令行工具转换。比如用obj2gltf把.obj转成.glb,命令长这样:obj2gltf -i input.obj -o output.glb。转换完记得检查法线方向,不然模型看起来像穿了隐身衣。

交互玩法整点花活

除了转圈缩放,还能通过JS监听模型点击事件。比如点恐龙的鼻子让它叫一声:

<model-viewer id="dino" src="dino.glb" camera-controls></model-viewer>
<script>
  const dino = document.getElementById('dino');
  dino.addEventListener('click', (ev) => {
    if (ev.detail?.faceIndex !== undefined) {
      new Audio('roar.mp3').play();
    }
  });
</script>

model-viewer的点击事件能返回点到的是模型的哪个面,所以可以做精准交互。不过原生的规范还没定这部分,得等社区吵完架再说。

目前最稳的生产环境方案还是,等过两年被各大浏览器实装了,再换成原生标签也不迟。毕竟前端这行,今天的新特性明天就成古董,能跑起来的代码才是好代码。