当前位置: 首页 > news >正文

Three.js 字体

请添加图片描述

在 Three.js 中,我们可以通过 FontLoader 加载字体,并结合 TextGeometry 创建 3D 文本。加载字体是因为字体文件包含了字体的几何信息,例如字体的形状、大小、粗细等,而 TextGeometry 则是根据字体信息生成 3D 文本的几何体。

在下面,我们将分别讲解加载字体和创建文本这两部分内容,并结合参数说明,让你对每一步都有深入理解。

加载字体和创建 3D 文本

Three.js 使用 FontLoader 来加载字体文件(格式为 .json),通过加载后的字体对象结合 TextGeometry 创建文本几何体。

加载字体:FontLoader

以下是使用 FontLoader 加载字体的代码:

const fontLoader = new THREE.FontLoader();// 加载字体文件(路径需要正确)
fontLoader.load("/path/to/font.json", (font) => {console.log("字体加载成功", font);// 使用加载的字体创建 3D 文本几何体const textGeometry = new THREE.TextGeometry("Hello Three.js!", {font: font, // 必须提供加载后的字体对象size: 1, // 字体大小height: 0.5, // 字体厚度curveSegments: 12, // 曲线分段数,值越大越平滑bevelEnabled: true, // 是否启用斜角bevelThickness: 0.03, // 斜角厚度bevelSize: 0.02, // 斜角大小bevelSegments: 5, // 斜角分段数});// 创建材质和网格const textMaterial = new THREE.MeshStandardMaterial({ color: 0xff6347 });const textMesh = new THREE.Mesh(textGeometry, textMaterial);// 设置文本位置textMesh.position.set(-5, 2, 0);// 添加到场景scene.add(textMesh);
});
TextGeometry 参数解析

TextGeometry 的构造函数中,我们需要传入两个参数:文本字符串和配置对象。

参数 1:文本字符串
  • 表示需要显示的文本内容,例如 'Hello Three.js!'
参数 2:配置对象

配置对象是一个 JSON,用于定义文本的样式和几何细节。以下是主要字段的详细说明:

参数名称类型默认值描述
fontTHREE.Font必须提供加载的字体对象,通过 FontLoader 加载后传入。
sizenumber100字体大小,值越大,文本越大。
heightnumber50字体厚度,用于创建 3D 效果。
curveSegmentsnumber12曲线分段数,值越大,曲线部分(如圆形字母)越平滑。
bevelEnabledbooleanfalse是否启用斜角。
bevelThicknessnumber10斜角的厚度,仅在启用斜角时有效。
bevelSizenumber8斜角的大小,表示斜角距离文本边缘的距离。
bevelSegmentsnumber3斜角的分段数,值越大斜角部分越平滑。

Three.js 的 FontLoader 仅支持 .json 格式的字体文件。如果是 .ttf 或其他格式,可以使用工具(如 Facetype.js)将其转换为 .json

例子

示例中,我们将创建一个 3D 文本效果,包含以下特性:

  • 使用 TextGeometry 创建立体文字
  • 添加斜角效果使文字边缘更加平滑
  • 使用 MeshPhongMaterial 材质实现高光效果
  • 通过环境光和方向光打造立体感
  • 实现文本自动居中显示
  • 支持通过鼠标交互旋转和缩放场景

效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们先看看创建 3D 文本的关键步骤:

  1. 加载字体
const fontLoader = new FontLoader();
fontLoader.load("https://threejs.org/examples/fonts/helvetiker_regular.typeface.json",(font) => {// 加载完成后的回调函数}
);
  1. 创建文本几何体
const textGeometry = new TextGeometry("Hello Three.js!", {font: font,size: 1, // 字体大小height: 0.2, // 文字厚度curveSegments: 12, // 曲线分段数bevelEnabled: true, // 启用斜角bevelThickness: 0.03,bevelSize: 0.02,bevelSegments: 5,
});
  1. 创建材质
const textMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00, // 绿色材质specular: 0x555555, // 高光颜色shininess: 30, // 高光强度
});const textMesh = new THREE.Mesh(textGeometry, textMaterial);
  1. 文本居中处理
textGeometry.computeBoundingBox();
const centerOffset =-0.5 * (textGeometry.boundingBox.max.x - textGeometry.boundingBox.min.x);
textMesh.position.x = centerOffset;

下面是完整代码

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);// 创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000
);
camera.position.z = 10;// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;// 添加灯光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);// 加载字体
const fontLoader = new FontLoader();fontLoader.load("https://threejs.org/examples/fonts/helvetiker_regular.typeface.json",(font) => {// 创建文本几何体const textGeometry = new TextGeometry("Hello Three.js!", {font: font,size: 1, // 字体大小height: 0.2, // 文字厚度curveSegments: 12, // 曲线分段数bevelEnabled: true, // 启用斜角bevelThickness: 0.03, // 斜角深度bevelSize: 0.02, // 斜角大小bevelOffset: 0, // 斜角偏移bevelSegments: 5, // 斜角分段数});// 创建材质const textMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00, // 绿色材质specular: 0x555555, // 高光颜色shininess: 30, // 高光强度});// 创建网格const textMesh = new THREE.Mesh(textGeometry, textMaterial);// 居中文本textGeometry.computeBoundingBox();const centerOffset =-0.5 * (textGeometry.boundingBox.max.x - textGeometry.boundingBox.min.x);textMesh.position.x = centerOffset;scene.add(textMesh);}
);// 动画循环
function animate() {requestAnimationFrame(animate);controls.update();renderer.render(scene, camera);
}// 处理窗口大小变化
window.addEventListener("resize", () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
});animate();

代码

github

https://github.com/calmound/threejs-demo/tree/main/font

gitee

https://gitee.com/calmound/threejs-demo/tree/main/font


http://www.mrgr.cn/news/81934.html

相关文章:

  • kotlin内联函数——runCatching
  • edge浏览器恢复旧版滚动条
  • ES7【2016】、ES8【2017】新增特性(六)
  • git 常用命令 git revert
  • 使用 configparser 读取 INI 配置文件
  • VMWARE linux LVM 扩容磁盘分区
  • html转PDF
  • NFS网络文件共享新认识——筑梦之路
  • HarmonyOS NEXT应用开发实战:一分钟写一个网络接口,JsonFormat插件推荐
  • ESP-IDF学习记录(3)ESP-IDF组件管理
  • 深入解析 Oracle 的聚合函数 ROLLUP
  • uniapp使用ucharts组件
  • 云计算学习架构篇之HTTP协议、Nginx常用模块与Nginx服务实战
  • SOME/IP 协议详解——远程过程调用(RPC)
  • Netty网络模型
  • SCAU高程进阶题(自用)
  • 谷云科技数据集成社区焕新登场:功能、资源、会员权益全面升级
  • Metricbeat安装教程——Linux——Metricbeat监控ES集群
  • ensp、HCL环境部署vm版
  • RCCL/NCCL中的Transports方式选择:P2P or SHM or NET
  • java开发配置文件集合
  • 【数据结构】Trie字典树(前缀树)— 数组实现
  • 为什么选择 RAG 技术?开启 AI 2.0 应用开发的新时代
  • 【bluedroid】A2dp Source播放流程源码分析(4)
  • 隧道FM广播信号、隧道内调频广播信号覆盖方案选择
  • elasticsearch-java客户端jar包中各模块的应用梳理