three.js中多线程的使用及性能测试详解


Posted in Javascript onJanuary 07, 2021

前言

今天郭先生说一下WebWorker以及WebWorker在three.js中的应用。我们都知道Javascript是单线程的,比如执行js代码的同时UI渲染就会停止,对于多核CPU的点脑,这一点让人难以接受,好在Web Worker的出现多少解决了一些问题。官方说Web Worker指的是一种可由脚本创建的后台任务,任务执行中可以向其创建者收发信息。要创建一个 Worker ,只须调用 Worker(URL) 构造函数,函数参数 URL 为指定的脚本。关于Web Worker的更多知识请阅读Web Worker。线案例请点击web-worker,

1. 在three.js中使用多线程

在three.js中使用Web Worker经常发生在大量计算造成CUP阻塞的情况下,我们举一个例子,比如说我们制作了1000个Mesh,

three.js中多线程的使用及性能测试详解

让他们简单的动起来,CPU几乎没有什么压力,FPS会在60左右,但是如果让这1000个Mesh的位置都需要大量计算才能得到,那么FPS就会很低(和计算量成负相关),下面是一段代码

for(let i=0; i<num; i++) {
 let angle = positions[i].y / (1000 / (Math.PI * 10));
 positions[i].x = positions[i].x + Math.sin(angle);
 positions[i].z = positions[i].z + Math.cos(angle);
 positions[i].y = positions[i].y + 1;
		//上面就是简单的位置变化,下面的代码模拟复杂的变化,累加100000次(这是非常占用线程的情况)
 for(let j=1, total=1; j<=100000; j++) {
 total += j;
 }
 if(positions[i].y > 500) {
 positions[i].y = positions[i].y - 1000;
 }
}
for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
}

positions是储存1000个Mesh位置信息的数组,group里面储存了所有的Mesh,每次渲染都更改positions的位置信息,然后给Group的每一个Mesh设置新值,这种情况下FPS会低至7FPS,转动场景可以很明显的感觉到卡顿。接下来我们使用Web Worker处理这个问题,主线程代码如下

myWorker = new Worker('/static/js/worker.js');
myWorker.postMessage(positions);
myWorker.onmessage = e => {
 let positions = e.data;
 for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
 }
}

脚本代码如下

onmessage = function(e) {
 let num = 1000;
 let positions = e.data;
 setInterval(e => {
 for(let i=0; i<num; i++) {
  let angle = positions[i].y / (1000 / (Math.PI * 10));
  positions[i].x = positions[i].x + Math.sin(angle);
  positions[i].z = positions[i].z + Math.cos(angle);
  positions[i].y = positions[i].y + 1;
  for(let j=1, total=1; j<=100000; j++) {
  total += j;
  }
  if(positions[i].y > 500) {
  positions[i].y = positions[i].y - 1000;
  }
 }
 postMessage(positions);
 }, 1000 / 60)
};

主要代码和未使用Web Worker几乎一样,只不过是将处理位置的代码放在新的线程中完成,setInterval定时器每一次完成位置计算都会通过postMessage(positions)将位置信息返回给主线程,主线程通过onmessage接受信息,返回对象的data属性就是新的positions。这样一来FPS可以达到60左右,转动场景感觉的到卡顿。这是十分让人欣喜的。

2. 性能分析

前面已经说了在每一次位置计算中做10万次累加,未使用Web Worker的情况下FPS降到了7,下面是更多的数据(数据仅做对比,和当前使用情况以及配合有关)。

累加次数(万次) 使用Web Worker 未使用Web Worker
1 60 60
3 60 39
5 60 26
7 60 11
9 60 8
11 60 6

这里面可以看出,不管是多么大量的计算,使用Web Worker都不会影响主线程,但是对于未使用Web Worker影响是十分严重的,下面展示一下两种情况下电脑性能的对比

(未使用Web Worker)

three.js中多线程的使用及性能测试详解

(使用Web Worker)

three.js中多线程的使用及性能测试详解

这里可以看出使用更多的线程可以很明显的提升CPU使用率。小伙伴们不妨打开线上案例亲自测试一下。

总结

到此这篇关于three.js中多线程的使用及性能测试的文章就介绍到这了,更多相关three.js多线程使用及性能测试内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

版权声明:本文为郭志强的原创文章,转载请附上原文出处链接及本声明。原文链接:https://www.mrguo.link

Javascript 相关文章推荐
JavaScript 编写匿名函数的几种方法
Feb 21 Javascript
JavaScript中的条件判断语句使用详解
Jun 03 Javascript
深入理解setTimeout函数和setInterval函数
May 20 Javascript
jQuery自定义图片缩放拖拽插件imageQ实现方法(附demo源码下载)
May 27 Javascript
基于WebUploader的文件上传js插件
Aug 19 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
Mar 04 Javascript
vue.js  父向子组件传参的实例代码
Oct 29 Javascript
微信小程序实现图片上传、删除和预览功能的方法
Dec 18 Javascript
ES6的异步终极解决方案分享
Jul 11 Javascript
jquery ui 实现 tab标签功能示例【测试可用】
Jul 25 jQuery
关于在LayUI中使用AJAX提交巨坑记录
Oct 25 Javascript
Vue实现多页签组件
Jan 14 Vue.js
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 #Vue.js
vuex的使用和简易实现
Jan 07 #Vue.js
vue watch监控对象的简单方法示例
Jan 07 #Vue.js
vue.js watch经常失效的场景与解决方案
Jan 07 #Vue.js
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 07 #Javascript
通过vue.extend实现消息提示弹框的方法记录
Jan 07 #Vue.js
如何在vue-cli中使用css-loader实现css module
Jan 07 #Vue.js
You might like
php中static静态变量的使用方法详解
2010/06/04 PHP
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
php开启openssl的方法
2014/05/15 PHP
PHP 中使用explode()函数切割字符串为数组的示例
2017/05/06 PHP
飞鱼(shqlsl) javascript作品集
2006/12/16 Javascript
Javascript 各浏览器的 Javascript 效率对比
2008/01/23 Javascript
JsDom 编程小结
2011/08/09 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
jquery实现横向图片轮播特效代码分享
2015/11/19 Javascript
浅析JavaScript函数的调用模式
2016/08/10 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
mpvue+vuex搭建小程序详细教程(完整步骤)
2018/09/30 Javascript
基于js实现抽红包并分配代码实例
2019/09/19 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
three.js利用射线Raycaster进行碰撞检测
2020/03/12 Javascript
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
Python实现抓取城市的PM2.5浓度和排名
2015/03/19 Python
Python调用系统底层API播放wav文件的方法
2017/08/11 Python
利用python求相邻数的方法示例
2017/08/18 Python
对python程序内存泄漏调试的记录
2018/06/11 Python
Python+selenium 获取一组元素属性值的实例
2018/06/22 Python
Python使用ffmpy将amr格式的音频转化为mp3格式的例子
2019/08/08 Python
django 通过url实现简单的权限控制的例子
2019/08/16 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
python多维数组分位数的求取方式
2020/03/03 Python
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
html table呈现个人简历以及单元格宽度失效的问题解决
2021/01/22 HTML / CSS
阿迪达斯希腊官方网上商店:adidas希腊
2019/04/06 全球购物
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
机电一体化专业应届生求职信
2013/11/27 职场文书
社区交通安全实施方案
2014/03/22 职场文书
远程培训的心得体会
2014/09/01 职场文书
遗嘱格式范本
2015/08/07 职场文书
Pyqt5将多个类组合在一个界面显示的完整示例
2021/09/04 Python