Three.js中FontLoader与TextGeometry导入异常及3D文本生成失败问题
问题解决:THREE.TextGeometry报错与导入、异步加载问题
1. 核心错误原因:异步加载处理不当
你的loadFont函数中,loader.load是异步操作,函数直接返回的是undefined,而非加载完成的THREE.Font实例,这导致TextGeometry抛出font parameter is not an instance of THREE.Font错误。异步操作无法同步返回结果,必须通过回调、Promise+async/await处理。
2. 正确的导入方式
FontLoader和TextGeometry不属于Three.js核心库,需单独导入,分两种场景:
ES6模块(npm安装three)
import * as THREE from 'three'; // 从addons模块导入所需类 import { FontLoader } from 'three/addons/loaders/FontLoader.js'; import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
CDN引入(script标签)
在核心Three.js脚本之后,引入对应的addons脚本:
<script src="https://cdn.jsdelivr.net/npm/three@latest/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/loaders/FontLoader.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/geometries/TextGeometry.js"></script>
3. 修正后的代码示例
方式一:Promise+async/await处理异步加载
// 封装字体加载为Promise loadFont = () => { return new Promise((resolve) => { const loader = new THREE.FontLoader(); loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', (font) => { resolve(font); }); }); } // 异步创建文本 createText = async () => { // 等待字体加载完成 const font = await this.loadFont(); this.textGeo = new THREE.TextGeometry("Hello", { font: font, size: 70, height: 20, curveSegments: 4, bevelThickness: 2, bevelSize: 1.5, bevelEnabled: true }); const materials = [ new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }), // 正面 new THREE.MeshPhongMaterial({ color: 0xffffff }) // 侧面 ]; this.textMesh1 = new THREE.Mesh(this.textGeo, materials); this.textMesh1.position.y = 80; this.textMesh1.position.z = 0; this.textMesh1.rotation.y = Math.PI * 2; // 仅需添加到场景一次 this.scene.add(this.textMesh1); }
方式二:直接在加载回调中创建文本
// 加载字体并触发文本创建 loadFontAndCreateText = () => { const loader = new THREE.FontLoader(); loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', (font) => { this.createText(font); }); } // 传入加载完成的字体创建文本 createText = (font) => { this.textGeo = new THREE.TextGeometry("Hello", { font: font, size: 70, height: 20, curveSegments: 4, bevelThickness: 2, bevelSize: 1.5, bevelEnabled: true }); const materials = [ new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }), // 正面 new THREE.MeshPhongMaterial({ color: 0xffffff }) // 侧面 ]; this.textMesh1 = new THREE.Mesh(this.textGeo, materials); this.textMesh1.position.y = 80; this.textMesh1.position.z = 0; this.textMesh1.rotation.y = Math.PI * 2; this.scene.add(this.textMesh1); }
额外注意事项
- 确保场景中存在光源(如
PointLight或DirectionalLight),MeshPhongMaterial需要光源才能显示颜色,否则文本会因无光照呈现黑色。 - 不要同时调用
this.scene.add和this.root.add,选择其中一个添加到场景层级即可,避免重复添加。
内容的提问来源于stack exchange,提问作者Satyam Raikwar
相关产品推荐
相关产品推荐

