Three.js使用TextBufferGeometry创建3D文本

学习交流欢迎加群: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>

猜你喜欢

转载自blog.csdn.net/qq_37338983/article/details/103037650