three.js 文本

There are many ways of displaying text inside a Three.js application: drawing text to a canvas and use it as a texture, importing a 3D model of a text, creating text geometry, and using bitmap fonts — or BMFonts. This last one has a bunch of helpful properties on how to render text into a scene.

在Three.js应用程序内显示文本的方法有很多:将文本绘制到画布上并将其用作纹理,导入文本的3D模型,创建文本几何图形以及使用位图字体(或BMFonts)。 最后一个关于如何将文本渲染到场景中的一堆有用的属性。

Text in WebGL opens many possibilities to create amazing things on the web. A great example is Sorry, Not Sorry by awesome folks at Resn or this refraction experiment by Jesper Vos. Let’s use Three.js with three-bmfont-text to create text in 3D and give it a nice look using shaders.

WebGL中的文本为在网络上创建惊人的事物提供了许多可能性。 一个很好的例子是Resn的优秀人员对不起,而不是对不起,或者Jesper Vos进行的折射实验。 让我们将Three.js与three-bmfont-text一起使用,以3D格式创建文本,并使用着色器为其提供漂亮外观。

Three-bmfont-text is a tool created by Matt DesLauriers and Jam3 that renders BMFont files in Three.js, allowing to batch glyphs into a single geometry. It also supports things like word-wrapping, kerning, and msdf — please watch Zach Tellman’s talk on distance fields, he explains it very good.

Three-bmfont-text是由Matt DesLauriers和Jam3创建的工具,用于在Three.js中呈现BMFont文件,从而可以将字形批量化为单个几何体。 它还支持自动换行,字距调整和msdf等功能-请观看Zach Tellman在距离场上的演讲,他解释得很好。

With all that said, let’s begin.

综上所述,让我们开始吧。

Attention: This tutorial assumes you have some understanding of 注意:本教程假定您对Three.js, GLSL shaders and Three.js ,GLSL着色器和glslify, so we’ll skip things like glslify有所了解,因此我们将跳过诸如how to set up a scene and import shaders.设置场景和导入着色器之类的操作。

入门 (Getting started)

Before everything, we need to load a font file to create a geometry three-bmfont-text provides packed with bitmap glyphs. Then, we load a texture atlas of the font which is a collection of all characters inside a single image. After loading is done, we’ll pass the geometry and material to a function that will initialize a Three.js setup. To generate these files check out this repository.

在开始之前,我们需要加载一个字体文件来创建一个几何图形,三个bmfont-text提供了位图字形。 然后,我们加载字体的纹理图集,该纹理图集是单个图像内所有字符的集合。 加载完成后,我们会将几何图形和材质传递给一个函数,该函数将初始化Three.js设置。 要生成这些文件,请签出该存储库。

const createGeometry = require('three-bmfont-text');
const loadFont = require('load-bmfont');loadFont('fonts/Lato.fnt', (err, font) => {// Create a geometry of packed bitmap glyphsconst geometry = createGeometry({font,text: 'OCEAN'});// Load texture containing font glyphsconst loader = new THREE.TextureLoader();loader.load('fonts/Lato.png', (texture) => {// Start and animate rendererinit(geometry, texture);animate();});
});

创建文本网格 (Creating the text mesh)

It’s time to create the mesh with the msdf shader three-bmfont-text comes with. This module has a default vertex and fragment shader that forms sharp text. We’ll change them later to produce a wavy effect.

是时候使用附带的msdf着色器创建3bmfont-text了。 该模块具有默认的顶点和片段着色器,可形成清晰的文本。 稍后我们将对其进行更改以产生波浪效果。

const MSDFShader = require('three-bmfont-text/shaders/msdf');function init(geometry, texture) {// Create material with msdf shader from three-bmfont-textconst material = new THREE.RawShaderMaterial(MSDFShader({map: texture,color: 0x000000, // We'll remove it later when defining the fragment shaderside: THREE.DoubleSide,transparent: true,negate: false,}));// Create mesh of text       const mesh = new THREE.Mesh(geometry, material);mesh.position.set(-80, 0, 0); // Move according to text sizemesh.rotation.set(Math.PI, 0, 0); // Spin to face correctlyscene.add(mesh);
}

And now the text should appear on screen. Cool, right? You can zoom and rotate with the mouse to see how crisp the text is.

现在文本应该出现在屏幕上。 酷吧? 您可以使用鼠标缩放和旋转以查看文本的清晰度。

演示地址

Let’s make it more interesting in the next step.

让我们在下一步变得更有趣。

GLSL (GLSL)

顶点着色器 (Vertex shader)

To oscillate the text, trigonometry is our best friend. We want to make a sinusoidal movement along the Y and Z axis — up and down, inside and outside the screen. A vertex shader fits the bill for this since it handles the position of the vertices of the mesh. But before this, let’s add the shaders to the material and create a time uniform that will fuel them.

为了使文本振荡,三角函数是我们最好的朋友。 我们希望沿着Y和Z轴(在屏幕的内部和外部)上下进行正弦运动。 顶点着色器适合此目的,因为它可以处理网格顶点的位置。 但是在此之前,让我们将着色器添加到材质中,并创建一个将为其加油的时间均匀性。

function init(geometry, texture) {// Create material with msdf shader from three-bmfont-textconst material = new THREE.RawShaderMaterial(MSDFShader({vertexShader,fragmentShader,map: texture,side: THREE.DoubleSide,transparent: true,negate: false,}));// Create time uniform from default uniforms objectmaterial.uniforms.time = { type: 'f', value: 0.0 };
}function animate() {requestAnimationFrame(animate);render();
}function render() {// Update time uniform each framemesh.material.uniforms.time.value = this.clock.getElapsedTime();mesh.material.uniformsNeedUpdate = true;renderer.render(scene, camera);
}

Then we’ll pass it to the vertex shader:

然后,将其传递给顶点着色器:

// Variable qualifiers that come with the msdf shader
attribute vec2 uv;
attribute vec4 position;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
varying vec2 vUv;
// We passed this one
uniform float time;void main() {vUv = uv;vec3 p = vec3(position.x, position.y, position.z);float frequency1 = 0.035;float amplitude1 = 20.0;float frequency2 = 0.025;float amplitude2 = 70.0;// Oscillate vertices up/downp.y += (sin(p.x * frequency1 + time) * 0.5 + 0.5) * amplitude1;// Oscillate vertices inside/outsidep.z += (sin(p.x * frequency2 + time) * 0.5 + 0.5) * amplitude2;gl_Position = projectionMatrix * modelViewMatrix * vec4(p, 1.0);
}

Frequency and amplitude are properties of a wave that determine their quantity and their “height”. Because we are using a sine wave to move the vertices, these properties can help control the behavior of the wave. I encourage you to tweak the values to observe different results.

频率和振幅是决定其数量和“高度”的波的属性。 因为我们使用正弦波移动顶点,所以这些属性可以帮助控制波的行为。 我鼓励您调整值以观察不同的结果。

Okay, so here is the tidal movement:

好的,这是潮汐运动:

演示地址

片段着色器(Fragment shader)

For the fragment shader, I thought about just interpolating between two shades of blue – a light and a dark one. Simple as that.

对于片段着色器,我考虑过仅在两种蓝色阴影之间进行插值-浅色和深色。 就那么简单。

The built-in GLSL function mix helps interpolating between two values. We can use it along with a cosine function mapped from 1 to 0, so it can go back and forth these values and change the color of the text — a value of 1 will give a dark blue and 0 a light blue, interpolating the colors between.

内置的GLSL函数混合有助于在两个值之间进行插值。 我们可以将其与从1到0映射的余弦函数一起使用,因此它可以来回移动这些值并更改文本的颜色-值1表示深蓝色,0表示浅蓝色,对颜色进行插值之间。

#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif// Variable qualifiers that come with the shader
precision highp float;
uniform float opacity;
uniform vec3 color;
uniform sampler2D map;
varying vec2 vUv;
// We passed this one
uniform float time;// HSL to RGB color conversion module
#pragma glslify: hsl2rgb = require(glsl-hsl2rgb)float median(float r, float g, float b) {return max(min(r, g), min(max(r, g), b));
}void main() {// This is the code that comes to produce msdfvec3 sample = texture2D(map, vUv).rgb;float sigDist = median(sample.r, sample.g, sample.b) - 0.5;float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);// Colorsvec3 lightBlue = hsl2rgb(202.0 / 360.0, 1.0, 0.5);vec3 navyBlue = hsl2rgb(238.0 / 360.0, 0.47, 0.31);// Goes from 1.0 to 0.0 and vice versafloat t = cos(time) * 0.5 + 0.5;// Interpolate from light to navy bluevec3 newColor = mix(lightBlue, navyBlue, t);gl_FragColor = vec4(newColor, alpha * opacity);if (gl_FragColor.a < 0.0001) discard;
}

And here it is! The final result:

在这里! 最终结果:

演示地址

其他例子(Other examples)

There is plenty of stuff one can do with three-bmfont-text. You can make words fall:

三bmfont文本可以做很多事情。 您可以使单词掉落:

演示地址

Enter and leave:

进入并离开:

演示地址

Distortion:

失真:

演示地址

Water blend:

水混合:

演示地址

Or mess with noise:

或杂乱无章:

演示地址

I encourage you to explore more to create something that gets you excited, and please share it with me via twitter or email. You can reach me there, too if you got any questions, or comment below.

我鼓励您探索更多内容,以创建让您兴奋的东西,并通过Twitter或电子邮件与我分享。 如果您有任何疑问或在下面发表评论,也可以在这里与我联系。

Hope you learned something new. Cheers!

希望你学到新东西。 干杯!

参考和鸣谢 (References and Credits)

  • Three.js

    Three.js

  • three-bmfont-text

    三字体字体文本

  • Glslify

    Glslify

  • Author of msdf

    msdf的作者

  • Generator for msdf files

    msdf文件的生成器

  • The Book of Shaders

    着色书

翻译自: https://tympanus.net/codrops/2019/10/10/create-text-in-three-js-with-three-bmfont-text/

three.js 文本

three.js 文本_使用Three-bmfont-text在Three.js中创建文本相关推荐

  1. word中创建文本框

    word中创建文本框         在插入中点击"文本框"选项卡,如下图所示:        手工添加自己想要的文本框格式,然后选择所创建的文本框,在工具栏处会发现多了一个&qu ...

  2. python查找并修改文件中的内容_如何使用Python搜索和替换文件中的文本?

    如何使用Python搜索和替换文件中的文本? 如何使用Python 3搜索和替换文件中的文本? 这是我的代码:import osimport sysimport fileinputprint (&qu ...

  3. python爬虫执行js代码_爬虫之python3用execjs执行JS代码

    JS运行环境 Node.js 是Javascript语言服务器端运行环境 测试运行 测试运行JavaScript程序 微软windows操作系统:附件-命令提示符 需进入到js程序的目录下,node命 ...

  4. aspnet中gridview文本只显示开始几个文本_软网推荐:三个小软件 轻松解决文本操作难题...

    TXT文本操作在Windows操作中算是比较容易的事了,但简单的文本操作也会遇到难题.例如,对于我们反复需要使用的多个信息,如果仅靠Ctrl+C和Ctrl+V来回复制.粘贴,效率会极低:再如,对于一些 ...

  5. sketch浮动布局_使用智能布局和调整大小在Sketch中创建更好的可重用符号

    sketch浮动布局 Sketch is a widely used tool for UI designs. It implemented the Sketch是用于UI设计的广泛使用的工具. 它实 ...

  6. Word控件Spire.Doc 【文本】教程(5) ;从 Word 文档中的文本框中提取文本

    文本框的目的是允许用户输入程序要使用的文本信息.也可以从文本框中提取现有的文本信息.以下指南重点介绍如何通过Spire.Doc for .NET从 C# 中 Word 文档的文本框中提取文本. Spi ...

  7. html代码文本框首行缩进,如何将HTML页面中的文本设置首行缩进

    text-indent属性介绍 属性值单位 描述 em 比如:1em 就代表缩进1个字,2em缩进2个字...... 由于简单我就不过多的介绍了直接上代码了哦,注意:text-indent属性的值支持 ...

  8. java中添加文本框_Java 添加、删除Word文档中的文本框

    在Word文档中,文本框是指一种可移动.可调大小的文字或图形容器.使用文本框,能够使文档在内容和形式上更为饱满.本文将通过使用Java编程来演示如何添加.删除Word文档中的文本框. Jar文件获取及 ...

  9. html代码文本框首行缩进,如何将HTML页面中的文本设置首行缩进,文本首行缩进...

    如何将HTML页面中的文本设置首行缩进,文本首行缩进 text-indent属性介绍 属性值单位 描述 em 比如:1em 就代表缩进1个字,2em缩进2个字...... 由于简单我就不过多的介绍了直 ...

  10. pc端文本_使用即将推出的Windows功能从PC发送文本

    pc端文本 Windows/Android/iPhone: Send and receive SMS messages on your PC, and access all the files on ...

最新文章

  1. Linux小实验——设备挂载、磁盘分区、格式化、RAID的配置、LVM配置、磁盘配额的配置方法和验证
  2. jvm 崩溃日志设置_JVM致命错误日志(hs_err_pid.log)分析(转载)
  3. [005] .NET 的执行模型
  4. python求函数极值_python 遗传算法求函数极值的实现代码
  5. jvm 助记符_您的JVM是否泄漏文件描述符-像我的一样?
  6. 前端学习(477):前端简介1
  7. ftm模块linux驱动,飞思卡尔k系列_ftm模块详解.doc
  8. 阿里云 APM 解决方案地图
  9. linux下php模式,linux下安装php两种模式区别
  10. java io 高级,JavaSE - [10] 高级部分之IO流
  11. 电商大促特辑:蘑菇街致美丽新世界的架构礼
  12. C11简洁之道:函数绑定
  13. 在我笔记本Ubuntu上装普罗米修斯记录
  14. 触动人心的手机端页面设计
  15. 微擎模块 抖音口红机 3.2.0+wap登陆1.3.0增加首页banner跳转链接
  16. DeepFlow:做好云原生时代的网络监控
  17. 调用函数,求加减乘除(基础)。
  18. 版号解禁,网络游戏却未解冻
  19. 华为防火墙企业双出口专线,配置策略路由实现多个ISP出接口的智能选路和双向NAT
  20. 取消超时订单及延迟处理方案

热门文章

  1. 求解积分的数值方法——Matlab实现
  2. JQuery EasyUI 1.5.1 美化主题大包
  3. scrapy爬取快代理并保存mongo数据库
  4. 视频教程-DelphiXE10安卓开发(实战篇)-其他
  5. 百度新营销:不只是关键词了
  6. canvas画笔功能 Signature Pad
  7. 云计算示范项目_“云计算和大数据”重点专项2018年度项目申报指南
  8. java 学生成绩管理系统_学生成绩管理系统
  9. ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区...
  10. windows 2012安装证书服务器,windows 2012 RADIUS服务器认证问题