ThreeJS中文字体乱码问题

本文介绍如何在 Three.js 中实现中文字符的显示,包括所需字体文件的转换及加载过程,提供了一个完整的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天刚刚接触ThreeJS,使用几天发现ThreeJS中默认是不支持中文的,只能显示英文,在网上找了一些资料,终于可以显示中文了。在此把显示中文的方法写下来,供大家参考,本人只是小白,大神勿喷。。。

1、默认的threejs包中会带一些字体,在examples中里面有个font文件夹,里面是threejs自带的一些字体格式


font问价夹里面就是这样的,默认带的字体格式是不支持中文的


2、想要显示中文,就需要我们自己引入自己的中文包,将ttf的字体格式转换为json或js文件格式

ttf字体格式需要在哪里找呢,在计算机中C盘,windows->Fonts->里面存放的就是各种计算机的各种字体格式.ttf文件(不过需要找一个小一点的,太大编辑器打开会崩掉的,这里我使用的是方正兰亭超细黑简体)


3、将之前找到的字体.ttf文件转换成json文件格式或js文件格式,使用的线上工具是http://gero3.github.io/facetype.js/

4、将转换后json文件加载到threejs中就可以了,再给字体附上属性,就可以展现中文汉字了

var loader = new THREE.FontLoader();
         //加载字体库,加载成功后将字体库传给回调函数;
         loader.load('font/FZLanTingHeiS-UL-GB_Regular.json',function(response){
                 var font = response;
                 /*创建字体几何图形,其中TextGeometry的第一个参数是需要绘制的文本,第二个参数是一个json对象,设置如何绘制文本,具体意义为:
                    font: 使用的字体库;
                    size:绘制字体的大小;
                    height:绘制文本的厚度;
                    bevelEnabled:是否允许棱角平滑过渡;
                    bevelSize:棱角平滑过渡的尺寸;*/
                 //注意:bevelSize通常要比size和height小一个量级,过渡带就会很饱满甚至比文本主体本身还要大


                 var textGeometry = new THREE.TextGeometry("学习Three.js",{
                     "font" : font,
                     "size" : 70,
                     "height" : 20,
                     "bevelEnabled" : true,
                     "bevelSize": 2
                 })

                 /*在3D世界里所有的物体都是由网格构成的,在three.js中,绘制图形的步骤是:
                先使用geometry定义图形的几何形状,然后使用几何形状和材质构建网格;*/

                 /*这里使用材质数组来对网格进行修饰,材质数组的第一项修饰文字正面和背面,
                 第二项修饰文字的侧面即顶部和底部。使用的两个材质都是MeshPhongMaterial,这种材质的特点是能够像塑料一样反光。*/
                 text = new THREE.Mesh(textGeometry,new THREE.MultiMaterial( [
                     new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } ),
                     new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.SmoothShading } )
                 ] ))

5、整个程序的源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>中文汉字</title>
    <script type="text/javascript" src="js/jquery-3.0.0.js"></script>
    <script src="js/three.min.r87.js"></script>
    <script type="text/javascript" src="js/CanvasRenderer.js"></script>
    <script type="text/javascript" src="js/Projector.js"></script>
    <script type="text/javascript" src="js/OrbitControls.js"></script>
    <script type="text/javascript" src="js/Stats.js"></script>

    <style type="text/css">
        *{
            padding:0px;margin: 0px
        }
        #container{
            width: 100%;
            height: 100vh;
        }
    </style>
</head>
<body>
<div id="container"></div>
 <script type="text/javascript">
     var renderer,scene,camera,controls;

     function initRenderer(){
         renderer = new THREE.WebGLRenderer( { antialias: true } );
         var width = document.getElementById("container").clientWidth;
         var height = document.getElementById("container").clientHeight;
         renderer.setSize(width,height);
         renderer.setClearColor(0xffffff);

         document.getElementById("container").appendChild(renderer.domElement);

     }

     function initScene(){
         scene = new THREE.Scene();
         scene.fog = new THREE.Fog( 0x000000, 0, 3000 );
     }

     function initCamera(){
         var width = document.getElementById("container").clientWidth;
         var height = document.getElementById("container").clientHeight;
         camera = new THREE.PerspectiveCamera(30, width/height,1, 10000);
         camera.position.y=800/Math.tan(Math.PI/2.5);
         camera.position.z=800;
     }

     function initLight(){
         var pointLight = new THREE.PointLight( 0xffffff, 1);
         pointLight.position.set( 0, 100, 100 );
         scene.add( pointLight );

         var pointLight = new THREE.PointLight( 0xffffff, 1);
         pointLight.position.set( 0, 100, -100 );
         scene.add( pointLight );
     }
     function initText(){
         var loader = new THREE.FontLoader();
         loader.load('font/FZLanTingHeiS-UL-GB_Regular.json',function(response){
                 var font = response;
                 
                 var textGeometry = new THREE.TextGeometry("学习Three.js",{
                     "font" : font,
                     "size" : 70,
                     "height" : 20,
                     "bevelEnabled" : true,
                     "bevelSize": 2
                 })

                 text = new THREE.Mesh(textGeometry,new THREE.MultiMaterial( [
                     new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } ),
                     new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.SmoothShading } )
                 ] ))

                 textGeometry.computeBoundingBox();

                 var centerOffset = -0.5 * (textGeometry.boundingBox.max.x-textGeometry.boundingBox.min.x);
                 text.position.x = centerOffset;
                 text.position.y = 30;

                 scene.add(text);
                 var plane = new THREE.Mesh(
                     new THREE.PlaneBufferGeometry( 10000, 10000 ),
                     new THREE.MeshBasicMaterial( { color: 0xfffffff, opacity: 0.5, transparent: true } )
                 );
                 plane.rotation.x = -Math.PI/2;
                 plane.position.y = 0;
                 scene.add(plane);
             })

     }
	 
     function initControls(){
         controls = new THREE.OrbitControls(camera);
         controls.enableZoom = true;
         controls.minPolarAngle = Math.PI/2.5;
         controls.maxPolarAngle = Math.PI/2.5;
     }

     function render(){
         renderer.render(scene, camera);
         requestAnimationFrame(render);
     }

     function start(){
         initRenderer();
         initScene();
         initCamera();
         initControls();
         initLight();
         initText();
         render();
     }

     start();


 </script>

</body>
</html>


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值