Skip to content

Three.js r184 推出 HTMLTexture:把活的 DOM 直接贴到 3D 表面

Three.js r184 本周发布。压轴功能是新增的 HTMLTexture 类,它让你能把任意活动的 HTML 元素当作纹理贴到网格上。按钮还能点击、输入框还能聚焦、CSS 动画照样滴答跑,无障碍和输入法的处理也全都交还给浏览器本身。

Chrome 官方介绍 HTMLTexture 背后的 HTML-in-Canvas API

一段话讲清 HTMLTexture

HTMLTexture 是对 Chrome 146 那套 HTML-in-Canvas API 的封装。你把一个 DOM 元素丢给它,Three.js 会在 canvas 上设置 layoutsubtree,把元素挂到渲染器的 DOM 里,然后把其光栅化输出投到一个 THREE.Texture 上,供 WebGL 2 或 WebGPU 上的任何材质采样。官方示例(webgl_materials_texture_htmlwebgpu_materials_texture_html)涵盖了格式化文字、图片、SVG、可用的输入框和按钮。

实际效果是:React 组件、设计系统控件、视频播放器、图表、甚至整张内嵌网页都可以贴在 Three.js 场景里的曲面屏、广告牌或 UI 面板上,而无需再做"先光栅化再丢掉交互"那一套折中。

注意事项

这项功能只在底层 API 存在的地方生效。眼下也就是开启 chrome://flags/#canvas-draw-element 标志的 Chromium 146+,意味着生产站点还需要回退方案。该 PR 在 API 不可用时让 HTMLTexture 优雅失败,但向客户承诺"完全可交互的 Three.js 仪表盘"之前,你还是想做一下特性检测。

Safari 和 Firefox 都没给出时间表。考虑到 WebGPU 自己也是 2025 年末才在三大浏览器达到基线,HTML-in-Canvas 大概也会走一条类似的两年路线。

在 Three.js 封装登场之前,社区对 HTML-in-Canvas 的一段早期演示

更要紧的一项:每帧零分配

不那么炫目、但实际上更重要的改动在渲染器的热路径上。在 r184 之前,以 60 FPS 渲染 1,000 个网格,每秒能制造 240,000 到 500,000 个一次性对象。任何一个跑得久点的场景,GC 都得不停为这些垃圾擦屁股。r184 在核心渲染循环里把这些分配全干掉了。长时间运行的 WebXR 会话、密集的建筑可视化、任何活过 30 秒的场景,都能白嫖一波帧时间的提升。

其他值得一提的小改动

AnimationAction 现在会在创建时保留插值设置,timeScale 反向也不会再跳变。AudioLoader 不再与加载管理器抢资源。BatchedMeshInstancedMesh 在颜色未设置时调用 getColorAt 不再抛错。已废弃的 WebGL 实例化渲染路径被彻底移除。示例新增了 SSGI 球池演示、3D Tiles 加载器里的体积云和大气,以及过山车摄像机的侧倾。

我们会拿它做什么

对 Cinevva 来说,最有意思的用例是 reels 播放器和创作者工具里画面之上的 UI。现在我们是把 HTML 叠在 Three.js 上。有了 HTMLTexture,聊天浮层、素材浏览器、提示词输入都可以直接活在场景里的几何体上,键盘导航也不会丢。等这个 API 在 Chrome 稳定版里默认开启,我们就会接一个受功能开关保护的变体进去。

参考资料