学习交流欢迎加群:789723098,博主会将一些demo整理共享
我们知道在Web前端上,可以用CSS样式设置多种多样的二维字体格式。如果我们想文本当成3D几何绘制在场景中,即生成3D文本来提升场景的逼格,可不可以呢?答案是肯定的,Three.js中提供了绘制文本的接口,TextGeometry和TextBufferGeometry,使用这两个接口,再配合FontLoader就可以实现3D字体的绘制和加载啦。
这里需要使用到Three.js的FontLoader来加载样式数据,然后对字体的样式进行设置:
loader = new FontLoader();
loader.load( 'fonts/gentilis_regular.typeface.json', ( font ) => {
// TODO 设置样式
})
等字体创建号之后,为了更加凸显字体的效果,可以使用OutlineEffect这个接口,对字体进行描边:
effect = new OutlineEffect( renderer );
effect.render( scene, camera );
下面笔者做了一个demo,先来看demo的效果:
Demo代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Text</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script type="module">
import {
Scene,
WebGLRenderer,
PerspectiveCamera,
FontLoader,
Color,
TextBufferGeometry,
MeshBasicMaterial,
Mesh,
Vector3,
SpotLight,
DirectionalLight,
AmbientLight,
} from "../build/three.module.js";
import { OutlineEffect } from "../examples/jsm/effects/OutlineEffect.js";
import Stats from './../examples/jsm/libs/stats.module.js';
import { GUI } from "../examples/jsm/libs/dat.gui.module.js";
import { OrbitControls } from "../examples/jsm/controls/OrbitControls.js";
let container, scene, renderer, camera, ambientLight, directionLight, loader, effect;
let gui, stats, orbit;
const w = window.innerWidth, h = window.innerHeight;
function initScene() {
container = document.createElement( 'div' );
document.body.append( container );
stats = new Stats();
container.appendChild( stats.domElement );
scene = new Scene();
scene.background = new Color( 0x339966 );
// scene.fog = new THREE.Fog( 0xffffff, 0x444444 );
renderer = new WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( w, h );
renderer.shadowMap.enabled = false;
container.appendChild( renderer.domElement );
renderer.gammaInput = true;
renderer.gammaOutput = true;
camera = new PerspectiveCamera( 45, w / h, 1, 1000 );
camera.position.set( 0, 0, 300 );
camera.lookAt( new Vector3( 0, 0, 0 ) );
orbit = new OrbitControls( camera, renderer.domElement );
orbit.enableZoom = true;
orbit.enableKeys = false;
ambientLight = new AmbientLight( 0x141414 );
scene.add( ambientLight );
directionLight = new DirectionalLight( 0xffffff );
directionLight.position.set( 0, 200, 100 );
directionLight.castShadow = true;
directionLight.shadow.camera.top = 180;
directionLight.shadow.camera.bottom = - 100;
directionLight.shadow.camera.left = - 120;
directionLight.shadow.camera.right = 120;
scene.add( directionLight );
loader = new FontLoader();
loader.load( 'fonts/gentilis_regular.typeface.json', ( font ) => {
addText( 'WebGL', font, new Vector3( - 60, 30, 0 ), 0xCC0000 );
addText( 'THREE.JS', font, new Vector3( - 30, 0, 0 ), 0x000000 );
addText( 'Graph', font, new Vector3( 80, 10, - 10 ), 0x669000 );
addText( 'TextBufferGeometry', font, new Vector3( - 0, - 30, 0 ), 0xffffff );
} );
effect = new OutlineEffect( renderer );
}
function addText( name, font, location, color ) {
let textGeometry = new TextBufferGeometry( name, {
font: font,
size: 20,
height: 2,
curveSegments: 10
} );
let textMaterial = new MeshBasicMaterial( { color: color } );
let textMesh = new Mesh( textGeometry, textMaterial );
textMesh.position.copy( location );
scene.add( textMesh );
}
function render() {
effect.render( scene, camera );
stats.update();
orbit.update();
requestAnimationFrame( render );
}
initScene();
render();
</script>
</body>
</html>