You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Three.js+Parcel加载字体报错Unsupported OpenType signature求助

解决Three.js + Parcel环境下TTFLoader加载字体出现“Unsupported OpenType signature”错误

问题描述

我有一个Three.js项目,采用Parcel作为模块打包工具,尝试通过Three.js的TTFLoader加载字体时,出现“Unsupported OpenType signature”错误。查阅相关问题后,排除了字体相对路径的问题,不清楚错误的真正根源。

错误信息

Unsupported OpenType signature

项目结构

项目根目录包含fonts文件夹(存放Mont-Regular.ttf字体文件)、核心业务文件app.js等。

报错代码片段(app.js)

// load font -- three font
const ttfLoader = new TTFLoader();

ttfLoader.load('fonts/Mont-Regular.ttf', (json) => {
   const font = new FontLoader(json);

   this.textGeo = new TextGeometry('Hello Text', {
      font: font,
      size: 200,
      height: 50,
      curveSegments: 12,
   });

   this.textMaterial = new THREE.MeshPhongMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
   });

   this.textMesh = new THREE.Mesh(this.textGeo, this.textMaterial);
   this.textMesh.position.set(0, 0, 0);
});

this.scene.add(this.textMesh);

问题根源与解决方法

1. FontLoader使用方式错误

TTFLoader加载完成后返回的是解析后的字体JSON对象,FontLoader本身是用于加载JSON格式字体文件的加载器,不能直接传入JSON对象实例化。正确做法是用Font类包装TTFLoader返回的JSON:

import { Font } from 'three/addons/loaders/FontLoader.js';

ttfLoader.load('fonts/Mont-Regular.ttf', (fontJson) => {
   const font = new Font(fontJson); // 使用Font类包装,而非FontLoader
   // 后续创建TextGeometry逻辑
});

2. Parcel资源处理异常

Parcel可能对TTF字体文件进行错误转码,导致TTFLoader无法解析原始二进制数据。可以通过以下方式修复:

  • 在项目根目录创建.parcelrc文件,添加规则禁止Parcel转码TTF文件:
{
  "transformers": {
    "*.ttf": ["@parcel/transformer-raw"]
  }
}
  • 或者通过ES模块导入方式获取字体的正确URL,避免路径解析问题:
import fontUrl from './fonts/Mont-Regular.ttf';

ttfLoader.load(fontUrl, (fontJson) => {
   // 后续逻辑
});

3. 异步加载导致的场景添加错误

ttfLoader.load是异步操作,你在加载完成前就执行了this.scene.add(this.textMesh),此时this.textMesh尚未初始化,会引发额外错误。需要将场景添加代码移到回调函数内部:

ttfLoader.load(fontUrl, (fontJson) => {
   const font = new Font(fontJson);
   this.textGeo = new TextGeometry('Hello Text', { 
      font: font,
      size: 200,
      height: 50,
      curveSegments: 12,
   });
   this.textMaterial = new THREE.MeshPhongMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
   });
   this.textMesh = new THREE.Mesh(this.textGeo, this.textMaterial);
   this.textMesh.position.set(0, 0, 0);
   this.scene.add(this.textMesh); // 移到回调内确保实例化完成
});

内容的提问来源于stack exchange,提问作者Reynald Lamury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:31:00