实用指南:【基础】Three.js 实现 3D 字体加载与 Matcap 金属质感效果(附案例代码)

news/2026/1/18 18:06:51/文章来源:https://www.cnblogs.com/gccbuaa/p/19498885

在 Three.js 中创建 3D 文本,是许多可视化效果、宣传页、粒子标题、互动展示中非常常见的需求。
要在三维空间里让文字真正“立起来”,通常会用到:

  • FontLoader:用于加载三维字体文件
  • TextGeometry / TextBufferGeometry:用于生成 3D 几何体
  • Matcap 材质:一种轻量级、表现力强的金属质感贴图材质
  • 以及一些小元素(如环、方块)增强场景的丰富度

请添加图片描述

一、准备字体文件

Three.js 并不能直接加载 .ttf.otf,需要把字体转换为 .typeface.json 格式。

字体文件可直接从 Three.js 仓库下载:

位置:
https://github.com/mrdoob/three.js/tree/dev/examples/fonts

你也可以自行转换字体文件,使用:
https://gero3.github.io/facetype.js/


二、加载 3D 字体

Three.js 提供了 FontLoader,用于异步加载 JSON 字体文件。

const fontLoader = new FontLoader();
//字体文件放在public目录下
fontLoader.load("/fonts/helvetiker_regular.typeface.json", (font) => {
console.log("字体加载完成");
// 生成文字几何体
const textGeometry = new TextGeometry("Hello Three.js", {
font,
size: 1,            // 字体大小
height: 0.2,        // 文字厚度
curveSegments: 5,   // 字体曲线细腻度
bevelEnabled: true, // 启用倒角
bevelThickness: 0.03,
bevelSize: 0.02,
bevelSegments: 3,
depth: 0.2,
});
textGeometry.center(); // 几何中心对齐
});

textGeometry.center() 有什么作用?

默认字体的原点在 左下角,不居中会导致旋转不对称。
调用 center() 后,会把字体的几何中心移动到坐标原点,使旋转更自然。


三、给文字添加 Matcap 材质(金属质感)

Matcap 是一种超轻量的“金属材质贴图”,不需要环境光,不需要灯光,不需要复杂的 PBR,渲染性能极佳。

示例 Matcap 资源库:
https://github.com/nidorx/matcaps

示例材质加载:

const matcap = new THREE.TextureLoader().load(
"/image/matcap-porcelain-white.jpg"
);
const material = new THREE.MeshMatcapMaterial({ matcap });

然后创建 Mesh:

textMesh = new THREE.Mesh(textGeometry, material);
scene.add(textMesh);

✨ Matcap 的优点

  • 不依赖光照,性能高
  • 表现力强(陶瓷、金属、复古、塑料…)
  • 完美适合 3D Logo、标题、展示页

四、为场景增加小元素(丰富视觉层次)

通过环面(Torus)和盒子(Box)可以构成一个有空间感的小宇宙,把 3D 字体“包围”起来。

const donutGeometry = new THREE.TorusGeometry(0.3, 0.2, 20, 45);
const boxGeometry = new THREE.BoxGeometry(0.6, 0.6, 0.6);
const matcapBlock = new THREE.TextureLoader().load(
"/image/blue-matcap.png"
);
const materialBlue = new THREE.MeshMatcapMaterial({ matcap: matcapBlock });
for (let i = 0; i < 50; i++) {
let mesh;
mesh = i % 2
? new THREE.Mesh(donutGeometry, materialBlue)
: new THREE.Mesh(boxGeometry, materialBlue);
// 随机位置
mesh.position.set(
(Math.random() - 0.5) * 15,
(Math.random() - 0.5) * 15,
(Math.random() - 0.5) * 15
);
// 随机旋转
mesh.setRotationFromEuler(
new THREE.Euler(
Math.PI * Math.random(),
Math.PI * Math.random(),
Math.PI * Math.random()
)
);
// 随机缩放
const radomeScale = Math.random() * 0.5 + 0.5;
mesh.scale.set(radomeScale, radomeScale, radomeScale);
meshs.push(mesh);
}

这些小方块和小甜甜圈让整个场景不再单调。


五、最终效果

在这里插入图片描述


六、完整代码

<script setup>import * as THREE from "three";import { OrbitControls } from "three/addons/controls/OrbitControls.js";import { onMounted, ref, onBeforeUnmount } from "vue";import VContainer from "@/components/v-container/Container.vue";import { FontLoader } from "three/examples/jsm/loaders/FontLoader.js";import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js";const threeRef = ref();let renderer = null;let scene = null;let controls = null;let camera = null;let textMesh = null;let meshs = [];const init = () => {// 场景scene = new THREE.Scene();scene.background = new THREE.Color(0x512da8);// 相机camera = new THREE.PerspectiveCamera(55,window.innerWidth / window.innerHeight,1,20000);camera.position.set(5, 5, 10);camera.lookAt(0, 0, 0);// 灯光// const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);// scene.add(ambientLight);// 1,加载字体(字体资源:https://github.com/mrdoob/three.js/tree/dev/examples/fonts)const fontLoader = new FontLoader();fontLoader.load("/fonts/helvetiker_regular.typeface.json", (font) => {console.log("字体加载完成");// 2,创建几何体const textGeometry = new TextGeometry("Hello Three.js", {font,size: 1,height: 0.2,curveSegments: 5, // 曲线分段数,越大越圆滑bevelEnabled: true, // 是否启用倒角bevelThickness: 0.03, // 倒角厚度bevelSize: 0.02, // 倒角大小bevelSegments: 3, // 倒角分段depth: 0.2, // 深度});// 3,几何体居中textGeometry.center(); // 几何体居中 (默认原点在文字的左下角)// 4,创建材质// a. 简单颜色// const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });// b. Matcap 材质(有金属质感)// 图片地址:https://github.com/mrdoob/three.js/blob/dev/examples/textures/matcaps/matcap-porcelain-white.jpgconst matcap = new THREE.TextureLoader().load("/image/matcap-porcelain-white.jpg");const material = new THREE.MeshMatcapMaterial({ matcap });// 3. 组合文字网格textMesh = new THREE.Mesh(textGeometry, material);scene.add(textMesh);// 创建周边小元素const donutGeometry = new THREE.TorusGeometry(0.3, 0.2, 20, 45);const boxGeometry = new THREE.BoxGeometry(0.6, 0.6, 0.6);// 图片地址:https://github.com/nidorx/matcaps/blob/master/256/046363_0CC3C3_049B9B_04ACAC-256px.pngconst matcapBlock = new THREE.TextureLoader().load("/image/blue-matcap.png"// "/image/9.png");const materialBlue = new THREE.MeshMatcapMaterial({ matcap: matcapBlock });for (let i = 0; i < 50; i++) {let mesh;if (i % 2) {mesh = new THREE.Mesh(donutGeometry, materialBlue);} else {mesh = new THREE.Mesh(boxGeometry, materialBlue);}mesh.position.set((Math.random() - 0.5) * 15,(Math.random() - 0.5) * 15,(Math.random() - 0.5) * 15);// 随机旋转mesh.setRotationFromEuler(new THREE.Euler(Math.PI * Math.random(),Math.PI * Math.random(),Math.PI * Math.random()));// 随机放大const radomeScale = Math.random() * 0.5 + 0.5;mesh.scale.set(radomeScale, radomeScale, radomeScale);meshs.push(mesh);}scene.add(...meshs);});const pointLight = new THREE.PointLight(0xffffff, 1.2);pointLight.position.set(10, 10, 10);scene.add(pointLight);// 渲染器renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿});renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器大小renderer.setPixelRatio(window.devicePixelRatio); // // 适应不同的设备屏幕threeRef.value.appendChild(renderer.domElement); // 将渲染器添加到DOM中// 轨道控制器controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true; //开启阻尼(惯性效果,视觉更自然)controls.dampingFactor = 0.25; //阻尼系数function animate() {requestAnimationFrame(animate);if (textMesh) {textMesh.rotation.y += 0.01;}meshs?.forEach((mesh) => {mesh.rotation.y += 0.01;mesh.rotation.x += 0.01;mesh.rotation.z += 0.01;});controls.update(); // 更新控制器renderer.render(scene, camera);}animate();};onMounted(() => {init();});onBeforeUnmount(() => {controls?.dispose();renderer?.dispose();scene?.traverse((obj) => {if (obj.isMesh) {obj.geometry.dispose();}});window.onresize = null;});
</script>
<template>
<div ref="threeRef" class="three-wrapper"></div>
</template><style scoped>.three-wrapper {width: 100%;height: calc(100vh); /* 调整高度以适应容器 */overflow: hidden;}
</style>

【基础】Three.js的零基础入门篇(附案例代码)
【基础】Three.js中添加操作面板,GUI可视化调试(附案例代码)
【基础】Three.js加载纹理贴图、加载外部gltf格式文件
【基础】Three.js中如何添加阴影(附案例代码)
✨【案例】Three.js 半球光与雪花降落场景(附案例代码)
✨【基础】Three.js中的粒子系统 (附案例代码)
✨【案例】Three.js 模拟水波纹与天空场景(附案例代码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1179006.shtml

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

相关文章

育儿心得(2026.01.18)

育儿心得(2026.01.18)最近,通过口才训练社小程序读了很多育儿方面的观点,听的时候觉得挺有道理,但实际和孩子在一起相处时又忘的一干二净。所以知易行难,一点不假,道理不仅要懂,更要践行,不然对你来说毫无价值…

LLM的基础知识总结

自监督学习&#xff08;Self-Supervised Learning-SSL&#xff09; 大语言模型&#xff08;LLM&#xff09;预训练阶段的核心技术之一&#xff0c;也是大模型具备通用能力的关键基础。 自监督学习是一种不需要人工标注数据的机器学习范式。 核心思路 从原始数据&#xff08;比如…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的多种类动物识别(Python+PySide6界面+训练代码)

摘要 本文详细介绍了一个基于YOLO系列目标检测算法的多类别动物识别系统。该系统结合了最新的YOLOv8算法以及其前代版本&#xff08;YOLOv7、YOLOv6、YOLOv5&#xff09;&#xff0c;通过Python编程语言和PySide6图形界面框架&#xff0c;实现了一个完整的动物识别解决方案。系…

第三章 异常(一)

第三章 异常(一) 条款9&#xff1a;利用destructors避免泄露资源 一、核心概念解析 首先&#xff0c;我们要理解这个条款解决的核心问题&#xff1a;手动管理资源&#xff08;如内存、文件句柄、网络连接等&#xff09;时&#xff0c;容易因忘记释放、程序提前退出&#xff08;…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的路面坑洞检测系统(Python+PySide6界面+训练代码)

摘要路面坑洞是道路基础设施的常见缺陷&#xff0c;对交通安全和车辆维护构成严重威胁。本文详细介绍了一个基于YOLO&#xff08;You Only Look Once&#xff09;系列深度学习模型的路面坑洞检测系统的完整实现方案。系统采用YOLOv5、YOLOv6、YOLOv7和YOLOv8等多种先进目标检测…

金仓数据库如何以“多模融合”重塑文档数据库新范式

文章目录前言性能实测&#xff1a;对标 MongoDB 7.0BSON 引擎对比 Oracle JSON多模融合的关键&#xff1a;不是“堆系统”&#xff0c;而是“一套内核”迁移体验&#xff1a;协议级兼容&#xff0c;替换成本更低高可用与统一运维&#xff1a;关键业务更看重确定性实践案例&…

2026 国产时序数据库全景盘点:从“单点极致”走向“多模融合”

2026 国产时序数据库全景盘点&#xff1a;从“单点极致”走向“多模融合”进入2026年&#xff0c;在“数字中国”与工业物联网浪潮的强劲推动下&#xff0c;国产时序数据库市场持续繁荣&#xff0c;竞争格局日趋清晰。本文将对当前主流的国产时序数据库进行梳理盘点&#xff0c…

Python+django的计算机教学活动教室预约系统聊天机器人

目录摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 Python与Django框架结合开发的计算机教学活动教室预约系统聊天机器人&#xff0c;旨在通过智能化交互提升教育资源的利用率与管…

完整教程:LeetCode 面试题 16.22. 兰顿蚂蚁

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

第三十三周 学习周报

摘要今日学习聚焦Fluent文件管理&#xff1a;掌握.msh、.cas、.dat核心文件作用&#xff0c;并对比.gz与.h5压缩格式的优缺点&#xff0c;为高效仿真文件存储提供选择依据。AbstractTodays learning focuses on Fluent file management: understanding the roles of core files…

213_尚硅谷_接口介绍和快速入门

213_尚硅谷_接口介绍和快速入门1.usb接口调用案例_实际物理接口 2.usb接口调用案例 3.usb接口调用案例_运行结果 4.手机接口案例分解 5.相机接口案例分解 6.电脑接口案例分解

【车载开发系列】AES-CMAC算法基础

【车载开发系列】AES-CMAC算法基础 【车载开发系列】AES-CMAC算法基础【车载开发系列】AES-CMAC算法基础一. 什么是AES二. AES密钥长度三. AES128算法特点四. AES实施步骤五. 算法应用六. 个人总结一. 什么是AES AES&#xff08;Advanced Encryption Standard&#xff09;是对…

2026国产时序数据库风云录:金仓“融合多模”架构异军突起

> 摘要&#xff1a;进入2026年&#xff0c;在“数字中国”与工业物联网浪潮的强劲推动下&#xff0c;国产时序数据库市场持续繁荣&#xff0c;竞争格局日趋清晰。本文将对当前主流的国产时序数据库进行梳理盘点&#xff0c;并特别聚焦于金仓数据库&#xff08;Kingbase&…

搭建 dnsmasq 服务器

dnsmasq 是一个轻量级的 DNS + DHCP + TFTP 集成服务,主要面向:小型网络 虚拟化环境 实验环境 容器 / K8s / OpenStack / libvirt 本地 DNS 缓存与域名解析它的核心特点是:配置简单、占用资源极低、启动快 dnsmasq …

Python+django的基于人脸识别的学生考勤请假选课软件系统

目录基于人脸识别的学生考勤请假选课系统&#xff08;PythonDjango&#xff09;开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;基于人脸识别的学生考勤请假选课系统&#xff08;PythonDjang…

【车载开发系列】安全算法与安全访问

【车载开发系列】安全算法与安全访问 【车载开发系列】安全算法与安全访问【车载开发系列】安全算法与安全访问一. 网络传输编码1&#xff09;Base64编码2&#xff09;十六进制编码二.四种加密算法1&#xff09;消息摘要算法&#xff08;摘要算法&#xff0c;哈希算法&#xff…

苍穹外卖学习 - day2

写在开头: 佛了,每次想起要写日记的时候,忙来忙去结果忘记写了,算了,先堆一些吧。目录: @目录写在开头:目录:今日完成今日收获12、redis基础今日完成实现了公共字段的自动填充,使用AOP切面的知识,在进行某系…

2025年市面上诚信的多媒体讲台电教桌公司排行,厂区监控杆/防雨套/化验室操作台厂家联系电话 - 品牌推荐师

行业洞察:多媒体讲台电教桌市场的竞争与机遇 随着教育信息化、智能化需求的持续攀升,多媒体讲台电教桌作为教学场景的核心设备,正经历从单一功能向集成化、定制化、智能化的深度转型。市场数据显示,2024年国内多媒…

P_X(x), P(X=1) 的区别;概率度量vs.概率分布

PX(x)P_X(x)PX​(x), P(X1)P(X1)P(X1) 的区别&#xff1b;概率度量vs.概率分布让我们用现实比喻来理解这个“简化计算”的概念。 比喻1&#xff1a;考试成绩统计 原始世界Ω&#xff1a;全班50个学生的完整试卷&#xff08;每道题的具体答案&#xff09; 张三的卷子李四的卷子王…

Python+django的基于学生行为的在线教育 学习选课成绩分析系统可视化统计图没有

目录基于学生行为的在线教育学习选课成绩分析系统可视化统计图摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;基于学生行为的在线教育学习选课成绩分析系统可视化统计图摘要 该系统采用…