Three.js 字体

news2025/1/5 6:21:57

请添加图片描述

在 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.coloradmin.cn/o/2267975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器人C++开源库The Robotics Library (RL)使用手册(三)

进入VS工程,我们先看看这些功能函数及其依赖库的分布关系: rl命名空间下,主要有八大模块。 搞定VS后将逐个拆解。 1、编译运行 根据报错提示,配置相应错误的库(根据每个人安装位置不同而不同,我的路径如下:) 编译所有,Release版本耗时大约10分钟。 以rlPlan运动…

【GUI-PyQt5】简介

1. 简介 GUI:带图形的用户接口程序,也就是桌面应用。 2. 分类 2.1 基本窗口控件 QMainWindowQwidgetQlabelQLineEdit菜单工具栏 2.2 高级组件 QTableViewQListView容器多线程 2.3 布局管理 QBoxLayoutQGridLayoutQFormLayout嵌套布局 2.4 信号与…

Mysql学习笔记之SQL-4

这篇文章开始介绍SQL语句的最后一个部分,DCL(Data Control Language)数据库控制语言。 1.简介 DCL英文全称是Data Control Language(数据控制语言),用来管理数据库用户、控制数据库的访 问权限。 这一部分比较简单,主…

Chrome被360导航篡改了怎么改回来?

一、Chrome被360导航篡改了怎么改回来? 查看是否被360主页锁定,地址栏输入chrome://version,看命令行end后面(蓝色部分),是否有https://hao.360.com/?srclm&lsn31c42a959f 修改步骤 第一步&#xff1a…

STM32-笔记18-呼吸灯

1、实验目的 使用定时器 4 通道 3 生成 PWM 波控制 LED1 ,实现呼吸灯效果。 频率:2kHz,PSC71,ARR499 利用定时器溢出公式 周期等于频率的倒数。故Tout 1/2KHZ;Ft 72MHZ PSC71(喜欢设置成Ft的倍数&…

内部类(2)

大家还,今天我们继续来学习内部类的知识,今天我们来看看其余几种内部类类型,那么话不多说 我们直接开始。 注:它是一个static的一个常量 一旦初始化就不能够进行修改了. 注:1.一般情况下我们定义常量的时候,会定成大写的: 2.a不…

Go Energy 跨平台框架 v2.5.1 发布

Energy 框架 是Go语言基于CEF 和 LCL 开发的跨平台 GUI 框架, 具体丰富的系统原生 UI 控件集, 丰富的 CEF 功能 API,简化且不失功能的 CEF 功能 API 使用。 特性? 特性描述跨平台支持 Windows, macOS, Linux简单Go语言的简单特性,使用简单…

欧科云链OKLink:比特币与以太坊“双重启动”将如何撬动市场?

近日,OKLink 与 137Labs 联合举办 X Space,围绕宏观经济环境、政策及机构投资的影响等话题,分享如何把握 Web3 中的潜在机会与辨别风险。OKG Research 首席研究员 Hedy、BuilderRocket Accelerator 研究合伙人 Vivienna、VC 分析员 Bunny、BU…

探索仓颉编程语言:功能、实战与展望

目录 引言 一.使用体验 二.功能剖析 1.丰富的数据类型与控制结构 2.强大的编程范式支持 3.标准库与模块系统 4.并发编程能力 三.实战案例 1.项目背景与目标 2.具体实现步骤 (1).导入必要的模块 (2).发送 HTTP 请求获取网页内容 (3).解析 HTML 页面提取文章信息 (…

JavaFX FXML模式下的布局

常见布局方式概述 在 JavaFX FXML 模式下,有多种布局方式可供选择。这些布局方式可以帮助您有效地组织和排列 UI 组件,以创建出美观且功能良好的用户界面。常用布局容器及布局方式 BorderPane 布局 特点:BorderPane 将空间划分为五个区域&…

OpenFeign介绍以及使用

介绍 OpenFeign 是一个声明式的 Web 服务客户端,用于简化在 Java 应用中调用 HTTP API 的过程,在 Spring Cloud 体系里被广泛应用,它有以下关键特性: 声明式调用:基于注解,开发人员只需定义接口并添加注解…

李永乐线性代数:A可逆,AX=B相关推论和例题解题思路

例题1: 思路讲解: 这个 (A-2E)可逆,所以有P(A-2E) E, 也就是(A-2E)的逆矩阵是P; 那么PA (A-2E)的逆 * A B P(A-2E,A)(E,B) 所以就可以直接求出B,也就是(A-2E)的逆 * A 例题2: 思路讲解:…

【Compose multiplatform教程18】多平台资源的设置和配置

要正确配置项目以使用多平台资源,请执行以下操作: 添加库依赖项。 为每种资源创建必要的目录。 为限定资源创建其他目录(例如,深色 UI 主题或本地化字符串的不同图像)。 依赖项和目录设置 要访问多平台项目中的资源…

Doris的SQL原理解析

今天来介绍下Doris的SQL原理解析,主要从语法、解析、分析、执行等几个方面来介绍,可以帮助大家对Doris底层有个清晰的理解~ 一、Doris简介 Apache Doris是一个基于MPP架构的高性能、实时的分析型数据库,能够较好的满足报表分析、即席查询、…

Excel for Finance 07 `FV PV` 函数

Excel 的 FV 函数用于计算一笔投资在未来的价值,基于固定的利率和定期付款。这是一个金融函数,常用来分析储蓄计划、贷款、或投资的增长。 语法: FV(rate, nper, pmt, [pv], [type])参数说明: rate(必需)&…

【运维】部署Gitea

部署Gitea Gitea文档 系统:Ubuntu 20.04.6 LTS 步骤: 准备数据库 使用内置 SQLite,无需额外准备。 下载安装 下载最新版本的 Gitea 并安装: wget -O gitea https://dl.gitea.com/gitea/version/gitea-version-linux-amd64 chm…

Redis KEYS查询大批量数据替代方案(推荐SCAN 命令)

文章目录 前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合(Sorted Set)3. 使用哈希(Hash)4. 使用 Redis 模块(如 RediSearch) 总结 前言 在使用 Redis 时,KEYS 命令虽然简单直接…

Apache Doris 创始人:何为“现代化”的数据仓库?

在 12 月 14 日的 Doris Summit Asia 2024 上,Apache Doris 创始人 & PMC 成员马如悦在开场演讲中,围绕“现代化数据仓库”这一主题,指出 3.0 版本是 Apache Doris 研发路程中的重要里程碑,他将这一进展总结为“实时之路”、“…

3. 指针、数组

目录 一、指针和数组 🍐 数组名指向首地址 🍊 例子 二、数组作为函数参数 🍋 数组名作为函数参数,为什么必须传递数组大小? 三、指针和字符数组 🍌怎么样存储一个string? &#x1f349…

upload-labs关卡记录14

让上传图片马,并且三种后缀都要上传成功才算成功: 先试试gif的吧: 可以上传,同理:查看源码 只检查了两个字节,我们直接修改一句话木马,先改后缀php为png,然后winhex修改头部就完了 …