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 相关文章推荐
location.href 在IE6中不跳转的解决方法与推荐使用代码
Jul 08 Javascript
jquery配合css简单实现返回顶部效果
Sep 30 Javascript
ActiveX控件与Javascript之间的交互示例
Jun 04 Javascript
AngularJS删除路由中的#符号的方法
Sep 20 Javascript
webpack+vue.js快速入门教程
Oct 12 Javascript
jQuery插件扩展实例【添加回调函数】
Nov 26 Javascript
利用Js+Css实现折纸动态导航效果实例源码
Jan 25 Javascript
JavaScript 复制对象与Object.assign方法无法实现深复制
Nov 02 Javascript
详解使用element-ui table组件的筛选功能的一个小坑
Nov 02 Javascript
node crawler如何添加promise支持
Feb 01 Javascript
2分钟实现一个Vue实时直播系统的示例代码
Jun 05 Javascript
js实现简单抽奖功能
Nov 24 Javascript
解决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实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
PHP获取毫秒级时间戳的方法
2015/04/15 PHP
php析构函数的简单使用说明
2015/08/24 PHP
分享五个PHP7性能优化提升技巧
2015/12/07 PHP
php实现购物车功能(上)
2020/07/23 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
2016/06/30 PHP
JQuery中的html()、text()、val()区别示例介绍
2014/09/01 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
javascript 中模板方法单例的实现方法
2017/10/17 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
2017/12/13 Javascript
详解如何写出一个利于扩展的vue路由配置
2019/05/16 Javascript
javascript异步处理与Jquery deferred对象用法总结
2019/06/04 jQuery
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
Node使用Selenium进行前端自动化操作的代码实现
2019/10/10 Javascript
vue flex 布局实现div均分自动换行的示例代码
2020/08/05 Javascript
Python中声明只包含一个元素的元组数据方法
2014/08/25 Python
python如何统计序列中元素
2020/07/31 Python
python 多个参数不为空校验方法
2019/02/14 Python
python 下 CMake 安装配置 OPENCV 4.1.1的方法
2019/09/30 Python
Python使用贪婪算法解决问题
2019/10/22 Python
Python操作SQLite/MySQL/LMDB数据库的方法
2019/11/07 Python
Python实现剪刀石头布小游戏(与电脑对战)
2019/12/31 Python
完美解决pycharm导入自己写的py文件爆红问题
2020/02/12 Python
英国第一家领先的在线处方眼镜零售商:Glasses Direct
2018/02/23 全球购物
美国家居用品和厨具购物网站:DealsDot
2019/10/07 全球购物
少年闰土教学反思
2014/02/22 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
2015年七夕爱情寄语
2015/03/24 职场文书
学校运动会加油词
2015/07/18 职场文书
会议室管理制度范本
2015/08/06 职场文书
教您怎么制定西餐厅运营方案 ?
2019/07/05 职场文书
销区经理年终述职报告模板
2019/11/28 职场文书
python中super()函数的理解与基本使用
2021/08/30 Python
mysql分表之后如何平滑上线详解
2021/11/01 MySQL