前言

由于公司的项目需要增加用户体验,而且图片尺寸比较大,动不动就会大于2k,4k,甚至更高。如果直接加载这样尺寸的图片,会需要很长时间,对于用户体验十分的不友好。
所以,需要首先加载一张小图,然后将整张大图分块进行加载,这样可以使用户第一时间查看的到图片,并且在一定的时间内,也将分块图片加载进来,更新纹理,提高清晰度。
最初我是通过canvas画布实现,创建一块完整图片大小的画布,首先将小图加载进去,然后让材质更新,显示出来当前的图片,然后每一块小块图加载完成,绘制到画布上面,设置material.map.needsUpdate为true来更新GPU的纹理。制作完成后,发现通过这种方式实现后,性能会有卡顿,每更新一次整张图片务必会影响性能。
最后,发现了Three.js的纹理局部更新的方法renderer.copyTextureToTexture可以实现,只更新局部数据,提高性能。接下来我们看一下这个方法如何使用。

方法使用

copyTextureToTexture ( position : Vector2, srcTexture : Texture, dstTexture : Texture, level : Number )

  • position — 当前更新纹理的起点位置,注意,这个位置是基于纹理的左下角开始的。
  • srcTexture —更新的块图,必须是一个Texture对象。
  • dstTexture — 将需要更新的纹理,前一个纹理将会从设置的起点开始绘制自身的高度和宽度的一块区域。
  • level — 指定纹理的细致程度。级别0是基本图像级别,级别n是第n个mipmap缩减级别。默认值为0,不写也可以 。

实际案例

有了这个方法以后,我就知道能够实现当前的局部更新功能。

首先是准备工作,我们需要的东西是整图的宽高和每一张的图片的大小和它在整张图上面所处于的位置。

然后,我们通过整张的尺寸创建一个纹理,并赋值给一个材质:

        material = new THREE.MeshBasicMaterial({map:new THREE.Texture()}); //创建材质let canvas = document.createElement("canvas");let ctx = canvas.getContext("2d");canvas.width = sceneBlockModel.sceneWidth;canvas.height = sceneBlockModel.sceneHeight;ctx.drawImage(img, 0, 0, sceneBlockModel.sceneWidth, sceneBlockModel.sceneHeight);material.map.image = canvas;material.map.minFilter = THREE.LinearFilter;material.map.generateMipmaps = false;material.map.needsUpdate = true;

这些工作在img图片加载完成后才可以制作。

然后就是把所有的分块图片加载到浏览器内,在加载完成时,触发回调,在相应的位置调用copyTextureToTexture更新纹理即可:

 //加载分块图片let xLen = Math.ceil(sceneBlockModel.sceneWidth / sceneBlockModel.fileBlockWidth);let yLen = Math.ceil(sceneBlockModel.sceneHeight / sceneBlockModel.fileBlockHeight);//延迟三秒开始加载分块图片setTimeout(function () {for (let x = 0; x < xLen; x++) {for (let y = 0; y < yLen; y++) {let img = new Image();img.src = sceneBlockModel.dir + x + "_" + y + ".jpg";img.onload = function () {let texture = new THREE.Texture(img);//获取渲染的起始位置let position = new THREE.Vector2();position.x = y * sceneBlockModel.fileBlockWidth;if (x === yLen - 1) {position.y = 0;}else {position.y = (yLen - 2 - x) * sceneBlockModel.fileBlockHeight + (sceneBlockModel.sceneHeight % sceneBlockModel.fileBlockHeight);}renderer.copyTextureToTexture(position, texture, material.map);}}}}, 3000);

案例里面我是设置延迟加载分块图片,由于图片是按照一定规则切块的,所以,我直接两个循环,通过计算位置,来实现的等位置渲染。

案例查看地址

https://www.wjceo.com/blog/threejs2/2018-11-02/179.html

103 THREE.JS 实现局部纹理刷新相关推荐

  1. Three.js(7):局部纹理刷新

    0 版本 vuecli:4.5.7 three.js:0.131.0 1 说明 局部纹理刷新主要是为了解决:图片较大导致加载纹理时候造成卡顿使得用户体验不友好,可是又想要加载高清的大图片提高清晰度. ...

  2. form表单刷新_《大胖 ? 小课》- 不用 js 实现文件无刷新上传

    这是<大胖小课>栏目的专题一<说说文件上传那些事儿>的第3节-<不用 js 实现文件无刷新上传> 专题已经更新章节: <大胖 • 小课>- 我是这样理解 ...

  3. java局部刷新session过期_Ajax局部页面刷新和History API结合的陷阱

    ajax在现代网站已经得到非常普遍地应用,主要的好处大家都知道(异步加载数据,不用刷新整个浏览器,更小的数据传输尺寸).对于那些老网站或者老项目来说全盘改造成ajax并不现实,于是就有了"局 ...

  4. 解决iscroll.js上拉下拉刷新手指划出屏幕页面无法回弹问题

    解决iscroll.js上拉下拉刷新手指划出屏幕页面无法回弹问题 参考文章: (1)解决iscroll.js上拉下拉刷新手指划出屏幕页面无法回弹问题 (2)https://www.cnblogs.co ...

  5. js app缓存自动刷新_如何通过清除缓存来刷新App Store中的内容

    js app缓存自动刷新 Are you finding that you're not seeing new apps on the App Store, or that updates to ap ...

  6. Flutter StatefulBuilder 用来实现局部数据刷新

    志在巅峰的攀登者,不会陶醉在沿途的某个脚印之中,在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的 ...

  7. js php 实时更新数字,js实现股票实时刷新数据案例

    近来学习炒股,免不了上班时间看盘,总不能光明正大的用电脑看行情,一直盯着手机影响也不好,容易引起"关注". 所以就想自己做一个网页来达到看盘的目的,一个只显示几个关键数字的网页肯定 ...

  8. 原生JS实现下拉刷新(移动端)

    原生JS实现下拉刷新(移动端) 主要利用touchstart.touchmove.touchend事件 结合CSS定位 <!DOCTYPE html> <html lang=&quo ...

  9. WebGL three.js学习笔记 纹理贴图模拟太阳系运转

    纹理贴图的应用以及实现一个太阳系的自转公转 点击查看demo演示 demo地址:https://nsytsqdtn.github.io/demo/solar/solar three.js中的纹理 纹理 ...

最新文章

  1. 38 JavaScript中的this指向问题
  2. YOLOv5-Lite 详解教程 | 嚼碎所有原理、训练自己数据集、TensorRT部署落地应有尽有...
  3. HDOJ---1257 最少拦截系统[线性DP]+NYOJ---拦截导弹[输出最长单调子序列的长度]
  4. Xamarin XAML语言教程对象元素的声明方式
  5. VC由进程ID获取窗口句柄的各种方
  6. iis 运行时错误_17个常见的Python运行时错误
  7. python实现不重复排列组合_Python实现输入字符串,返回其任意排列组合
  8. linux各种压缩包使用方法
  9. 前端学习(2346):global全局样式布局
  10. 新品发布、降价普惠、拥抱开源、出海全球化 | 杭州云栖企业数字化转型峰会上的那些关键词
  11. 18-elasticsearch集群健康为黄色
  12. linux转为root用户_[R] 展示linux文件树 - collapsibleTree
  13. 关于Axure RP
  14. java 对象赋值给scala_将Scala变量转换为Java对象… varargs
  15. 7大前端项目速览!非一线城市也吃香!
  16. java applet介绍,Java Applet教程介绍
  17. 加权平均数的例子_EXCEL 加权平均数的计算
  18. 计算机无法用u盘重装系统,最简单不用U盘电脑重装系统教程
  19. java lang ClassCastException java lang Integer cannot be ca
  20. 游戏配音中常见的节奏类型

热门文章

  1. Python 实现黑白棋
  2. 我用24次离职,换来6条血一样的教训
  3. Oracle实验 实验1 Oracle数据库安装与配置
  4. Android开发之监听手机来电
  5. 微信小程序 云开发表数据一键清空
  6. C#学习笔记----C#连接MySQL数据库
  7. angular 日期选择器_使用Angular,Bulma和Moment.JS构建日期时间范围选择器
  8. hdu2121 朱刘算法不定根
  9. 概率论的学习和整理--番外11:10球里8红球2白球,抽俩次抽中白球的概率是多少呢? 一个例题的不同方法
  10. JES-java emil server搭建