使用three.js创建大小不随着场景变化的文字
使用three.js创建大小不随着场景变化的文字,需要以下两步:
1、将文字绘制到画布上。
2、创建着色器材质,把文字放到三维场景中。
优点:
1、跟用html实现文字相比,这些文字可以被模型遮挡,更具有三维效果。
2、不会随着场景旋转缩放改变尺寸,不存在远处看不清的情况,适用于三维标注。
效果图:

示例代码1:https://github.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/object/text/UnscaledText.js
示例代码2:https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/object/text/UnscaledText.js
实现方法
1、使用canvas绘制文字,先用黑色绘制描边,然后用白色绘制文字。黑色描边主要为了让文字在白色背景处能看清。
let context = canvas.getContext('2d');
context.imageSmoothingQuality = 'high';
context.textBaseline = 'middle';
context.textAlign = 'center';
context.lineWidth = 4;
let halfWidth = canvas.width / 2;
let halfHeight = canvas.height / 2;
// 画描边
context.font = `16px "Microsoft YaHei"`;
context.strokeStyle = '#000';
context.strokeText(text, halfWidth, halfHeight);
// 画文字
context.fillStyle = '#fff';
context.fillText(text, halfWidth, halfHeight);
2、 创建着色器材质,将文字正对屏幕,渲染到三维场景中。
let geometry = new THREE.PlaneBufferGeometry();
let material = new THREE.ShaderMaterial({
vertexShader: UnscaledTextVertexShader,
fragmentShader: UnscaledTextFragmentShader,
uniforms: {
tDiffuse: {
value: new THREE.CanvasTexture(canvas)
},
width: {
value: canvas.width
},
height: {
value: canvas.height
},
domWidth: {
value: renderer.domElement.width
},
domHeight: {
value: renderer.domElement.height
}
},
transparent: true
}); let mesh = new THREE.Mesh(geometry, material);
说明:由于canvas上绘制的文字边缘是半透明的,材质要设置成半透明才能实现文字边缘平滑效果。
precision highp float; uniform float width;
uniform float height;
uniform float domWidth;
uniform float domHeight; varying vec2 vUv; void main() {
vUv = uv;
vec4 proj = projectionMatrix * modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
gl_Position = vec4(
proj.x / proj.w + position.x * width / domWidth * 2.0,
proj.y / proj.w + position.y * height / domHeight * 2.0,
proj.z / proj.w,
1.0
);
}
说明:
a、(0.0, 0.0, 0.0)是平面中心世界坐标,左乘modelViewMatrix和projectionMatrix后,得到屏幕坐标系中的坐标。
b、proj.x / proj.w + position.x * width / domWidth * 2.0的意思是把平板中心放到世界坐标系正确位置,让平板显示的宽度恰好等于屏幕上的像素数,避免文字缩放。
c、乘以2.0是因为three.js默认生成的平板宽度和高度是1,屏幕坐标系宽度和高度都是从-1到1,是2。
d、gl_Position.w为1.0时,是正投影,模型大小不随着屏幕深度变化而改变。
precision highp float; uniform sampler2D tDiffuse;
uniform float width;
uniform float height; varying vec2 vUv; void main() {
// 注意vUv一定要从画布整数坐标取颜色,否则会导致文字模糊问题。
vec2 _uv = vec2(
(floor(vUv.s * width) + 0.5) / width,
(floor(vUv.t * height) + 0.5) / height
); gl_FragColor = texture2D( tDiffuse, _uv );
}
说明:
1、uv坐标一定要恰好对应画布上的像素点,否则会导致文字模糊问题。
文字模糊的解决方法
vec2 _uv = vec2(
(floor(vUv.s * width) + 0.5) / width,
(floor(vUv.t * height) + 0.5) / height
);
参考资料
使用three.js创建大小不随着场景变化的文字的更多相关文章
- Qt QLabel 大小随内容自动变化 && 内容填充整个label空间
图1:label的本身大小 图2:给label设置文字,不做任何别的设置 ui->label->setText(QObject::tr("current font is %1&q ...
- 第一章 用three.js创建你的第一个3D场景
第一章 用three.js创建你的第一个3D场景 到官网下载three.js的源码和示例. 创建HTML框架界面 第一个示例的代码如下: 01-basic-skeleton.html 位于 Learn ...
- 使用three.js创建3D机房模型-分享一
序:前段时间公司一次研讨会上,一市场部同事展现了同行业其他公司的3D机房,我司领导觉得这个可以研究研究,为了节约成本,我们在网上大量检索,最后找到一位前辈的博文[TWaver的技术博客],在那篇博文的 ...
- Spring boot+Thymeleaf+easyui集成:js创建组件页面报错
开发工具:Ideal 使用场景:Demo 前提: 环境:Spring boot +Thymeleaf+easyui 引入thymeleaf模板引擎 <html lang=" ...
- 使用webgl(three.js)创建3D机房,3D机房微模块详细介绍(升级版二)
序: 上节课已经详细描述了普通机房的实现过程,文章地址(https://www.cnblogs.com/yeyunfei/p/10473021.html) 紧接着上节课的内容 我们这节可来详细讲解机房 ...
- 使用webgl(three.js)创建3D机房(升级版)-普通机房
序: 目前市面上的数据中心主要分两大类,一类属于普通数据中心,机柜按照XY轴 有序排放,一类属于微模块集合的数据中心,多个机柜组合而成的微模块. 本节课主要详细讲解普通数据中心的可视化展示,浏览器直 ...
- 用Backbone.js创建一个联系人管理系统(五)
原文: Build a Contacts Manager Using Backbone.js: Part 5 这是这系列教程最后一部分了. 之前所有的增删改都在前端完成. 这部分我们要把Contact ...
- 使用 iosOverlay.js 创建 iOS 风格的提示和通知
iosOverlay.js 用于在 Web 项目中实现 iOS 风格的通知和提示效果.为了防止图标加载的时候闪烁,你需要预加载的图像资源.不兼容 CSS 动画的浏览器需要 jQuery 支持.浏览器兼 ...
- Dynamics.js - 创建逼真的物理动画的 JS 库
Dynamics.js 是一个用来创建物理动画 JavaScript 库.你只需要把dynamics.js引入你的页面,然后就可以激活任何 DOM 元素的 CSS 属性动画,也可以用户 SVG 属性. ...
随机推荐
- spring cloud 调用接口间歇性返回http 500 - Internal Server Error的错误
查找了各种资料都没找到解决办法,token失效,网络问题,接口服务问题,基础服务问题,都考虑过,但是没能解决,偶尔发现服务器网络配置中存在一个virbr0虚拟网卡,问了下了网管,删除这个对服务并没有影 ...
- 【已解决】ArcGIS Engine无法创建拓扑的问题(CreateTopology)
也许,你的问题是这样的 ①System.Runtime.InteropServices.COMException:"未找到拓扑." ②myTopology结果是null,程序跳转到 ...
- XSS与CSRF详解
XSS与CSRF详解 随着Web2.0.社交网络.微博等等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上,Web业务的迅速发展也引起 ...
- [Scala]Scala安装以及在IDEA中配置Scala
一 Scala简述 Scala (斯卡拉)是一门多范式(multi-paradigm)的编程语言. 这里所谓的范式,指的是编写程序的方式,不同的编程语言,方式也不尽相同,也就意味着Scala编程语言 ...
- TCP/IP协议指南
分组: packet 通常用来表示任何类型的报文. 数据报: datagram 表示网络分层技术,它也经常用于表示在OSI参考模型较高层上的发送报文. 帧: frame 特别常见用于数据链路层上的报文 ...
- docker已运行容器添加或修改端口映射
# 不推荐方法:将原来的容器提交成镜像,然后利用新的建立的镜像重新建立一个带有端口映射的容器# 推荐方法:## 查看id 就是 容器的 hash_of_the_container 数值 docker ...
- MySQL集群搭建详解(三种结点分离)
本文将搭建一个最简化的MySQL Cluster系统,配置方法中的所有命令都是以root账户运行.这个MySQL Cluster包含一个管理结点.两个数据结点.两个SQL结点,这五个结点会分别安装在五 ...
- csps模拟测试57
T1 天空龙 大神题,考察多方面知识,例如:快读 附上考试代码,以供后人学习 应某迪要求,我决定多写一点. 正如文化课有知识性失分和非知识性失分一样,OI也同样存在. 但非知识性失分往往比知识性失分更 ...
- 用Java实现简单的区块链
用 Java 实现简单的区块链 1. 概述 本文中,我们将学习区块链技术的基本概念.也将根据概念使用 Java 来实现一个基本的应用程序. 进一步,我们将讨论一些先进的概念以及该技术的实际应用. 2. ...
- JavaScript入门经典(第7版)读书笔记
断断续续看了十来天,终于看完了,还是学到些东西,这本书还是不错的,各方面都有涉及. 补充了下之前不完善的JS 知识 笔记一般只记必要的东西. Table of Contents 1. JavaScr ...