创建文本

在 three.js 应用中,你经常需要用到文本——下面是几种实现方式。

1. DOM + CSS

使用 HTML 通常是添加文本最简单、最快捷的方式。大多数 three.js 示例中的描述性叠加层都采用了这种方法。

你可以向某个元素添加内容,例如:

<div id="info">Description</div>

然后使用 CSS 将其绝对定位,并通过 z-index 使其显示在所有其他元素之上,尤其是在 three.js 全屏运行时。

#info {
  position: absolute;
  top: 10px;
  width: 100%;
  text-align: center;
  z-index: 100;
  display:block;
}

2. 使用 `CSS2DRenderer` 或 `CSS3DRenderer`

使用这些渲染器可以将包含在 DOM 元素中的高质量文本绘制到 three.js 场景中。 这与方法 1 类似,但元素能更紧密、更动态地融入场景。

3. 将文本绘制到 canvas 上并用作 `Texture`

如果你希望在 three.js 场景中的平面上轻松绘制文本,可以使用此方法。

4. 在你常用的 3D 应用中创建模型并导出到 three.js

如果你更喜欢使用 3D 建模应用来制作模型,然后导入到 three.js 中,可以使用此方法。

5. 程序化文本几何体

如果你更倾向于完全在 THREE.js 中工作,或者需要创建程序化、动态的 3D 文本几何体, 可以创建一个网格,其几何体是 THREE.TextGeometry 的实例:

new THREE.TextGeometry( text, parameters );

不过要使其正常工作,TextGeometry 的 `font` 参数需要设置为一个 THREE.Font 实例。 请参阅 `TextGeometry` 页面,了解如何设置字体、各参数的说明,以及 THREE.js 发行版自带的 JSON 字体列表。

示例

[example:webgl_geometry_text WebGL / geometry / text]
[example:webgl_shadowmap WebGL / shadowmap]

如果 Typeface 不可用,或你想使用其中没有的字体,可参考一个教程, 其中包含用于 Blender 的 Python 脚本,可将文本导出为 Three.js 的 JSON 格式: [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html]

6. 位图字体

BMFonts(位图字体)允许将字形批量合并到单个 BufferGeometry 中。BMFont 渲染支持自动换行、字母间距、字距调整、带标准导数的有符号距离场、多通道有符号距离场、多纹理字体等。 参阅 [link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui] 或 [link:https://github.com/Jam3/three-bmfont-text three-bmfont-text]。

现成的字体可以在 [link:https://github.com/etiennepinchon/aframe-fonts A-Frame Fonts] 等项目中找到, 你也可以从任何 .TTF 字体创建自己的位图字体,并优化为仅包含项目所需的字符。

一些有用的工具:

  • [link:http://msdf-bmfont.donmccurdy.com/ msdf-bmfont-web] (基于 Web)
  • [link:https://github.com/soimy/msdf-bmfont-xml msdf-bmfont-xml] (命令行)
  • [link:https://github.com/libgdx/libgdx/wiki/Hiero hiero] (桌面应用)

7. Troika Text

[link:https://www.npmjs.com/package/troika-three-text troika-three-text] 该包使用与 BMFonts 类似的技术渲染高质量抗锯齿文本,但可以直接使用任何 .TTF 或 .WOFF 字体文件,无需离线预生成字形纹理。它还提供了以下功能:

  • 描边、投影和弯曲等效果
  • 可以应用任何 three.js 材质,甚至是自定义 ShaderMaterial
  • 支持连字、连写字母书写体系(如阿拉伯文),以及从右到左/双向排版
  • 针对大量动态文本进行了优化,大部分工作在 Web Worker 中完成,避免占用主线程