用Three.js搞个炫酷3D字体

简介: 三角形飞啊飞~飞啊飞~飞到一起,成了彩色字体!点击进来就看如何用three.js实现炫酷3D字体!!

点进来就看炫酷的3D字体!

1.准备工作:字体模型json

可以通过facetype.js将字体包转成typeface.json

facetype.jsgithub链接:https://github.com/gero3/facetype.js
facetype.js官网链接:http://gero3.github.io/facetype.js/

9329584c7e1c43ec839562de9a3fa6e4~tplv-k3u1fbpfcp-watermark.png

2.加载字体

if (!this.loader) {
   
   
            this.loader = new THREE.FontLoader();
          }
          this.loader.load('DIN_Bold.json', (font) => {
   
   

            //...
            });

3.创建字体并获取字体点面

 //创建字体图形
            let geometry = new THREE.TextGeometry(that.text, {
   
   
              font: font,
              size: that.fontSize, //字体大小
              height: that.thickness, //字体厚度
              curveSegments: 3,
              bevelThickness: 2,
              bevelSize: 1,
              bevelEnabled: true
            });

             //图形居中
            geometry.center();

            //转为缓存图形,方便获取点面等数据
            geometry = new THREE.BufferGeometry().fromGeometry(geometry);
            //三角形面数
            const numFaces = geometry.attributes.position.count / 3;

4.字体形状赋值颜色

 //需要赋值的点颜色数组
            const colors = new Float32Array(numFaces * 3 * 3);

         const color = new THREE.Color();

            for (let f = 0; f < numFaces; f++) {
   
   
              const index = 9 * f;
              //随机颜色
              color.setRGB(
                Math.random() * 0.5 + 0.5,
                Math.random() * 0.5 + 0.5,
                Math.random() * 0.5 + 0.5
              );


              for (let i = 0; i < 3; i++) {
   
   
                //给3个点赋值同样的颜色,形成一个颜色的三角形
                colors[index + 3 * i] = color.r;
                colors[index + 3 * i + 1] = color.g;
                colors[index + 3 * i + 2] = color.b;

              }
            }
            //设置顶点着色器值
            geometry.setAttribute('aColor', new THREE.BufferAttribute(colors, 3));

5.着色器材质

5.1 顶点着色器

                  attribute vec3 aColor; 
                  varying vec3 vColor;
                  void main() {
                      vColor = aColor; 
                      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

                  }

5.2 片元着色器

  varying vec3 vColor;
      void main() {
              gl_FragColor =vec4(vColor, 1.0 );

      }

5.3 着色材质

//着色器材质
            const shaderMaterial = new THREE.ShaderMaterial({
   
   
              uniforms: {
   
   
                amplitude: {
   
    value: 0.0 }
              },
              vertexShader: document.getElementById('vertexshader').textContent,
              fragmentShader: document.getElementById('fragmentshader').textContent
            });

6.使用

  var myFont = new MyFont();
      myFont.initThree(document.getElementById('font'));
      myFont.createChart({
   
   
        text: '666',//文本
        fontSize: 20,//字体大小
        thickness: 5,//厚度
        distance: 30,//偏移距离
        minDistance: 5,//最小偏移距离 
      });

2.gif

7.字体每个面的偏移

顶点着色器normal是three顶点着色器默认值

                  attribute vec3 aColor;  
                  varying vec3 vColor;

                  void main() {
                      vColor = aColor; 
      vec3 newPosition =position+normal*2.0;//每个面偏移                       
        gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
                  }

3.gif

8.让每个面三角形随机偏移

                   attribute vec3 aColor;
                   attribute vec3 displacement; //偏移值
                   varying vec3 vColor; 

                   void main() {
                       vColor = aColor; 

       vec3 newPosition =position+normal*displacement;//每个面随机偏移
   gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );

                   }

设置随机偏移值

   //需要赋值的偏移变量数组
            const displacement = new Float32Array(numFaces * 3 * 3);
      for (let f = 0; f < numFaces; f++) {
   
   
              const index = 9 * f;

              //随机偏移值
              const d = that.minDistance + that.distance * Math.random();

              for (let i = 0; i < 3; i++) {
   
   

                //给3个点赋值偏移值,形成对应的三角形
                displacement[index + 3 * i] = d;
                displacement[index + 3 * i + 1] = d + Math.random() * that.minDistance;
                displacement[index + 3 * i + 2] = d + Math.random() * that.minDistance;
              }
            }
            //设置顶点着色器值            
            geometry.setAttribute('displacement', new THREE.BufferAttribute(displacement, 3));

4.gif

9.随机偏移的三角形汇聚成原来的字体

9.1 偏移

uniform float time;
 attribute vec3 aColor;
                   attribute vec3 displacement; //偏移值
                   varying vec3 vColor; 

                   void main() {
                       vColor = aColor; 

       vec3 newPosition =position+normal*displacement*time;//每个面随机偏移随时间变
   gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );

                   }

9.2 汇聚

让偏移值随时间递减到0,汇聚成原来的字体,则时间值递减

5.gif

 animateAction() {
   
   
          if (this.mesh) {
   
   
            if (this.time >= 0) {
   
   
              this.time += 0.005;
              this.mesh.material.uniforms.time.value = 2.0 - this.time;
              if (this.time >= 2.0) {
   
   
                this.time = -1;
              }
            } else {
   
   
              this.mesh.material.uniforms.time.value = 0.0;
            }
          }
        }

10.字体面数细化

        import {
   
    TessellateModifier } from '../node_modules/three/examples/jsm/modifiers/TessellateModifier.js';

         //细化修改器            
            const tessellateModifier = new TessellateModifier(8, 6);
            //修改图形的面数
            geometry = tessellateModifier.modify(geometry);

6.gif

细化修改器 TessellateModifier( maxEdgeLength=0.1 最大边长, maxIterations = 6 最大遍历次数, maxFaces = Infinity 最大面数 )

可以看到相对于原来的字体,面数增加了,更加精细了!

11.同理可在其他模型形状也可使用该效果


   let geometry = new THREE.CylinderGeometry(that.topRadius, that.bottomRadius, that.height);
          //图形居中
          geometry.center();
          //细化修改器
          const tessellateModifier = new TessellateModifier(8, 6);
          //修改图形的面数
          geometry = tessellateModifier.modify(geometry);

          //转为缓存图形,方便获取点面等数据
          geometry = new THREE.BufferGeometry().fromGeometry(geometry);
          //...

7.gif

GitHub地址

http://github.com/xiaolidan00/my-three

参考:https://threejs.org/examples/#webgl_modifier_tessellation

相关文章
|
4月前
|
JavaScript
js实现图片3D轮播效果(收藏)
js实现图片3D轮播效果(收藏)
55 0
|
4月前
three.js的3D模型渲染主要构成
three.js的3D模型渲染主要构成
87 0
|
JavaScript 前端开发 索引
用Three.js搞个炫酷3D地球
地球人怎么可以不会画地球!从canvas画地球贴图开始,用Three.js手把手教你实现一个炫酷的3D地球!
用Three.js搞个炫酷3D地球
|
1月前
|
编解码 缓存 算法
Three.js如何降低3D模型的大小以便更快加载
为加快600MB的3D模型在Three.js中的加载速度,可采用多种压缩方法:1) 减少顶点数,使用简化工具或LOD技术;2) 压缩纹理,降低分辨率或转为KTX2等格式;3) 采用高效文件格式如glTF 2.0及draco压缩;4) 合并材质减少数量;5) 利用Three.js内置优化如BufferGeometry;6) 按需分批加载模型;7) Web Workers后台处理;8) 多模型合并减少绘制;9) 使用Texture Atlas及专业优化工具。示例代码展示了使用GLTFLoader加载优化后的模型。
179 12
|
1月前
|
存储 JavaScript 前端开发
小白实战!用JS实现一个3D翻书效果,附上代码
小白实战!用JS实现一个3D翻书效果,附上代码
|
1月前
|
存储 JavaScript 前端开发
使用JS创造一个3D粒子化星空,十分酷炫,大家快进来看看吧
使用JS创造一个3D粒子化星空,十分酷炫,大家快进来看看吧
|
4月前
|
JavaScript 开发工具 git
Three.js第1篇,Three.js新手教学,如何在项目中使用Three.js(three.js使用流程详细,three.js的使用方式,three.js创建3d物体)
Three.js封装了WebGL的底层细节,是一款运行在浏览器中的 3D 引擎,可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象,目前在Git上已经拥有90k+的star。
79 0
Three.js第1篇,Three.js新手教学,如何在项目中使用Three.js(three.js使用流程详细,three.js的使用方式,three.js创建3d物体)
|
11月前
|
存储 数据可视化 JavaScript
Three.js:打造独一无二的3D模型可视化编辑神器!
因为之前工作过的可视化大屏项目开发3d大屏组件模块需要用到Three.js来完成,其主功能是实现对3d模型的材质,灯光,背景,动画。等属性进行可视化的编辑操作以及模型编辑数据的存储和模型在大屏上面的拖拽显示
504 1
Three.js:打造独一无二的3D模型可视化编辑神器!
|
9月前
|
人工智能 JavaScript Linux
基于Three.js的3D自动纹理化开发包
DreamTexture.js 基于 Three.js 和稳定扩散(stable diffusion) AI 模型开发,用于实现 3D 模型的自动纹理化。
86 0
|
10月前
|
JavaScript 小程序
小程序通过js控制页面字体颜色属性
小程序通过js控制页面字体颜色属性
77 0