位置: IT常识 - 正文

【Three.js】渲染模型卡顿的优化办法(threejs loader)

编辑:rootadmin
【Three.js】渲染模型卡顿的优化办法 事先说明

推荐整理分享【Three.js】渲染模型卡顿的优化办法(threejs loader),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:js渲染3d模型,threejs demo,three.js效果,threejs demo,threejs怎么提高渲染效率,js渲染3d模型,threejs渲染器,threejs渲染器,内容如对您有帮助,希望把文章链接给更多的朋友!

优化方法是根据chatGPT的回答下,我这里记录一下,有的方法进行了尝试,有的还没有。

1、模型面数过多导致渲染卡顿

可以通过减少面数来优化,也可以使用LOD技术(Level of Detail)在不同距离下使用不同的模型细节来优化。

使用LOD技术可以在不同距离下使用不同的模型细节来优化three.js渲染性能,下面是具体步骤:

创建多个模型,每个模型的面数和细节不同,这些模型应该是同一个对象的不同版本。

将这些模型按照从低到高的细节顺序添加到同一个LOD(Level of Detail)对象中,如下所示:

const lod = new THREE.LOD();const lowDetailModel = ... // 低细节模型const midDetailModel = ... // 中细节模型const highDetailModel = ... // 高细节模型lod.addLevel(lowDetailModel, 0); // 添加低细节模型,距离为0lod.addLevel(midDetailModel, 100); // 添加中细节模型,距离为100lod.addLevel(highDetailModel, 200); // 添加高细节模型,距离为200将LOD对象添加到场景中。scene.add(lod);在渲染循环中,根据相机与LOD对象的距离,自动选择当前需要显示的模型细节等级。可以使用THREE.LOD对象的update方法来实现。function render() { requestAnimationFrame(render); lod.update(camera); renderer.render(scene, camera);}2、材质贴图过大导致渲染卡顿

可以通过减小贴图尺寸,压缩贴图格式,使用纹理集(Texture Atlas)等方式来优化。

使用纹理集(Texture Atlas)可以将多张小纹理图合并成一张大纹理图,从而减少渲染时的纹理切换次数,优化three.js渲染性能,下面是具体步骤:

创建一张大纹理图,并将多张小纹理图拼接在一起,这些小纹理图应该是同一对象的不同部分,如下所示:const texture = new THREE.TextureLoader().load('atlas.png');const material = new THREE.MeshBasicMaterial({ map: texture });将每个物体的UV坐标映射到对应的小纹理图区域,需要根据小纹理图在大纹理图中的位置和大小计算出UV坐标,如下所示:const geometry = new THREE.BoxGeometry(1, 1, 1);const uvAttribute = geometry.attributes.uv;for (let i = 0; i < uvAttribute.count; i++) { const u = uvAttribute.getX(i); const v = uvAttribute.getY(i); // 根据小纹理图在大纹理图中的位置和大小计算出UV坐标 uvAttribute.setXY(i, u * smallTextureWidth / bigTextureWidth + smallTextureX / bigTextureWidth, v * smallTextureHeight / bigTextureHeight + smallTextureY / bigTextureHeight);}在渲染循环中,更新大纹理图的偏移和缩放值。function render() { requestAnimationFrame(render); const time = Date.now() * 0.001; texture.offset.x = time * 0.1; // x方向偏移量 texture.offset.y = time * 0.2; // y方向偏移量 texture.repeat.set(2, 2); // 横向和纵向缩放值 renderer.render(scene, camera);}3、着色器复杂度过高导致渲染卡顿

可以通过简化着色器,使用预编译的着色器,使用Instancing等方式来优化。

【Three.js】渲染模型卡顿的优化办法(threejs loader)

使用Instancing(实例化)可以将多个相同的物体复用同一个几何体和材质,并在渲染时进行一次性绘制,从而减少渲染调用次数,优化three.js渲染性能,下面是具体步骤:

创建一个几何体和材质,将它们分别作为多个物体的原型。const geometry = new THREE.BoxGeometry(1, 1, 1);const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });创建一个InstancedBufferGeometry对象,并将原型几何体的属性复制到它的属性中。const instances = 10000; // 实例数量const instancedGeometry = new THREE.InstancedBufferGeometry();instancedGeometry.copy(geometry); // 复制几何体属性const translations = new Float32Array(instances * 3); // 实例位置数组for (let i = 0; i < instances; i++) { translations[i * 3] = Math.random() * 100 - 50; translations[i * 3 + 1] = Math.random() * 100 - 50; translations[i * 3 + 2] = Math.random() * 100 - 50;}instancedGeometry.setAttribute('translation', new THREE.InstancedBufferAttribute(translations, 3));创建一个InstancedMesh对象,并将原型材质和实例化几何体作为它的参数。const instancedMesh = new THREE.InstancedMesh(instancedGeometry, material, instances);scene.add(instancedMesh);在渲染循环中,更新实例化几何体的属性,即实例的位置、旋转和缩放等信息。function render() { requestAnimationFrame(render); const time = Date.now() * 0.001; for (let i = 0; i < instances; i++) { const translation = instancedMesh.geometry.attributes.translation; translation.setXYZ(i, Math.sin(time + i * 0.5) * 5, Math.cos(time + i * 0.3) * 5, i * 0.1); } instancedMesh.geometry.attributes.translation.needsUpdate = true; // 更新实例位置属性 renderer.render(scene, camera);}4、不合理的渲染方式导致渲染卡顿

可以通过使用合适的渲染方式,如WebGL2渲染,使用Web Worker等方式来优化。

Ⅰ、使用WebGL2可以在现代浏览器中利用新的图形处理能力,优化three.js渲染性能,下面是具体步骤: ① 在渲染器中启用WebGL2。

const renderer = new THREE.WebGLRenderer({ canvas: canvas, context: canvas.getContext('webgl2') });

② 使用WebGL2支持的新特性,如transform feedback、instanced arrays等。 例如,以下代码演示了如何使用transform feedback来记录顶点位置的变化:

const transformFeedback = new THREE.WebGL2TransformFeedback();const bufferGeometry = new THREE.BufferGeometry();const positions = new Float32Array([0, 0, 0]);bufferGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));const shader = new THREE.ShaderMaterial({ vertexShader: ` out vec3 transformedPosition; void main() { transformedPosition = position; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` void main() { gl_FragColor = vec4(1.0); } `, transformFeedback: { // 将顶点位置记录到transformedPosition变量中 varyings: ['transformedPosition'], // 开启transform feedback enabled: true, // 设置bufferGeometry的位置属性为transform feedback的输出属性 bufferGeometry: bufferGeometry }});const mesh = new THREE.Mesh(bufferGeometry, shader);scene.add(mesh);function render() { requestAnimationFrame(render); renderer.setRenderTarget(null); // 开始transform feedback transformFeedback.begin(); renderer.render(scene, camera); // 结束transform feedback,并将变化后的顶点位置存储到bufferGeometry中 transformFeedback.end(); // 更新顶点位置 positions.set(bufferGeometry.getAttribute('position').array); bufferGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); renderer.render(scene, camera);}

---------------------------------------------------------------分隔线-----------------------------------------------------------------

Ⅱ、使用Web Worker可以将计算密集型的任务分离到另一个线程中,从而避免主线程被阻塞,优化three.js渲染性能,下面是具体步骤:

① 创建一个Web Worker,用于处理计算密集型的任务。

const worker = new Worker('worker.js');

② 在Web Worker中定义处理函数。

// worker.jsfunction process(data) { // 计算密集型的任务 return result;}onmessage = function(event) { const result = process(event.data); postMessage(result);};

③ 在主线程中将任务发送到Web Worker,并设置回调函数处理返回结果。

function render() { requestAnimationFrame(render); // 发送任务到Web Worker worker.postMessage(data); worker.onmessage = function(event) { const result = event.data; // 处理返回结果 }; renderer.render(scene, camera);}

通过以上步骤,就可以使用Web Worker来将计算密集型的任务分离到另一个线程中,从而避免主线程被阻塞,优化three.js渲染性能。需要注意的是,Web Worker中无法直接访问主线程的DOM和three.js对象,需要通过消息传递来实现通信。

5、CPU和GPU资源不平衡导致渲染卡顿

可以通过分析性能监控,优化代码逻辑,使用requestAnimationFrame等方式来平衡CPU和GPU资源占用。

使用requestAnimationFrame可以让浏览器根据自身的渲染节奏调整动画的帧率,从而避免过度渲染,优化three.js渲染性能,下面是具体步骤:

将渲染函数作为requestAnimationFrame的回调函数。function render() { // 渲染代码 renderer.render(scene, camera); // 请求下一帧动画 requestAnimationFrame(render);}在初始化时调用一次requestAnimationFrame,启动动画。var animationId = requestAnimationFrame(render);在动画结束时,记得停止requestAnimationFrame,以避免不必要的资源消耗。function stop() { cancelAnimationFrame(animationId);}

需要注意的是,使用requestAnimationFrame时需要避免在渲染循环中进行过多的计算,以免影响渲染性能。

本文链接地址:https://www.jiuchutong.com/zhishi/287108.html 转载请保留说明!

上一篇:enternet.exe是安全的进程吗 enternet进程信息查询(enter an integer)

下一篇:伊莎贝尔二世桥,塞维利亚 (© Zu Sanchez Photography/Getty Images)(伊莎贝尔公主)

  • iphonexr home键怎么调出来(苹果xr调出home键)

    iphonexr home键怎么调出来(苹果xr调出home键)

  • 微信个人轨迹查看在哪里(微信个人轨迹查询方法)

    微信个人轨迹查看在哪里(微信个人轨迹查询方法)

  • 若要设定打印纸张大小在word 2010中可在什么进行(若要设定打印纸张大小,应使用)

    若要设定打印纸张大小在word 2010中可在什么进行(若要设定打印纸张大小,应使用)

  • qq怎么储存表情包(怎么保存qq表情到手机)

    qq怎么储存表情包(怎么保存qq表情到手机)

  • plc的软件系统可分为哪两大部分(plc的软件系统可分为应用软件)

    plc的软件系统可分为哪两大部分(plc的软件系统可分为应用软件)

  • 电脑主机后面的插孔分别是什么(电脑主机后面的音频插孔图)

    电脑主机后面的插孔分别是什么(电脑主机后面的音频插孔图)

  • 可以查看qq群是被谁举报的吗(qq群能看自己是几号入群的吗)

    可以查看qq群是被谁举报的吗(qq群能看自己是几号入群的吗)

  • 华为返回键怎么调整到右边(华为返回键怎么弄)

    华为返回键怎么调整到右边(华为返回键怎么弄)

  • 京东商家不发货平台会怎么处理(京东商家不发货怎么申请赔付)

    京东商家不发货平台会怎么处理(京东商家不发货怎么申请赔付)

  • 苹果11长宽高是多少厘米(苹果11长宽度)

    苹果11长宽高是多少厘米(苹果11长宽度)

  • iphone8是a11还是a12(iphone8是a10还是a11)

    iphone8是a11还是a12(iphone8是a10还是a11)

  • 服务器地址怎么填(服务器地址怎么写)

    服务器地址怎么填(服务器地址怎么写)

  • 为什么抖音直播一个人都没有(为什么抖音直播间打字别人看不见)

    为什么抖音直播一个人都没有(为什么抖音直播间打字别人看不见)

  • 微信微云在哪里打开文件(微信微云在哪里找到)

    微信微云在哪里打开文件(微信微云在哪里找到)

  • 魅族16型号叫什么(魅族16的型号)

    魅族16型号叫什么(魅族16的型号)

  • 美团怎么开通到店自取(美团官网登录入口)

    美团怎么开通到店自取(美团官网登录入口)

  • 11pro夜景模式怎么开(11pro相机夜景模式怎么开)

    11pro夜景模式怎么开(11pro相机夜景模式怎么开)

  • 手机淘宝夜间模式在哪(手机淘宝夜间模式在哪里设置)

    手机淘宝夜间模式在哪(手机淘宝夜间模式在哪里设置)

  • 小米8充不进去电(小米8充不进去电须要关机重启才可以)

    小米8充不进去电(小米8充不进去电须要关机重启才可以)

  • 计算机主机主要包括(电脑主机)

    计算机主机主要包括(电脑主机)

  • 快手推广作品别人知道吗(快手推广作品别人能看到推广两字吗)

    快手推广作品别人知道吗(快手推广作品别人能看到推广两字吗)

  • 摄像头3mp什么意思(摄像头3m5m什么意思)

    摄像头3mp什么意思(摄像头3m5m什么意思)

  • 小米手机定位怎么关(小米手机定位怎么改变自己的位置)

    小米手机定位怎么关(小米手机定位怎么改变自己的位置)

  • 文件夹属性中没有共享选项卡(文件夹属性没有安全)

    文件夹属性中没有共享选项卡(文件夹属性没有安全)

  • 240hz显示器推荐,五款240hz专业电竞显示器推荐(台式机显示器推荐)

    240hz显示器推荐,五款240hz专业电竞显示器推荐(台式机显示器推荐)

  • 个人能否申请延迟退休
  • 出口退税政策
  • 稳岗返还多久能到账
  • 买的矿泉水可以烧开吗
  • 自然人生产经营所得,如何计算个税
  • 什么叫发票分割单
  • 银行结息收入怎么做分录
  • 公司预付签证费怎么入账
  • 单位注销合并时在原单位各个账户余额保留
  • 企业买电动车做资产如何做折旧?
  • 旅行社小规模纳税人增值税怎么征税
  • 企业单位名称变更说明
  • 老板带员工出去吃饭
  • 投资税收抵免
  • 汇算清缴之前找回来成本发票可以吗
  • 旅行社开的发票是否都要差额征税
  • 应付职工薪酬在借方是什么意思
  • 跨年度冲减收入
  • 建筑工程分包怎么纳税
  • 中级会计考试考后审核需要什么资料
  • 免税收入税额的含义
  • php多维数组转一维数组
  • win10系统如何开启蓝牙
  • php file_get_contents 读取图片
  • Skype.exe - Skype是什么进程 有什么用
  • 商品先入库后得发票如何做账
  • 企业的留存收益可以抵税吗
  • 跨年调整收入增值税怎么办
  • win11大小核调度会优化吗
  • 利用php将图片转为文字
  • 建筑企业总包单位有哪些
  • 燃气管道安装费和暖气管道安装费两个的欠条怎么写
  • mac安装mysql8.0
  • 软件和硬件如何分开
  • 本期发生的下列业务中,根据权责发生制原则
  • 企业付给个人工资怎么算
  • 纳税人识别号是不是税号
  • 四联发票都需要盖章吗
  • 存货周转率是指企业某一会计
  • 制造业企业无形资产怎么摊销
  • 豆腐是农产品还是工业产品
  • 如何确认产品销售收入
  • 安全生产费会计核算办法
  • 用于出口的进项发票怎么做账
  • 公司交残保金是什么意思
  • 预收款开票的会计分录
  • 凭证摘要写错了已结账了怎么办
  • 低值易耗品入账
  • 集团公司对子公司总经理的绩效考核
  • 哪些行为应作为证据
  • mysql字段名可以用中文吗
  • Mac OS10.11下mysql5.7.12 安装配置方法图文教程
  • windows电脑设置
  • window10怎么启用net 3.5
  • mac系统删除系统软件
  • unable to boot - please use a kernel appropriate for your cpu的解决方法
  • windows1021h2更新
  • linux修改用户名
  • nomoreporn.exe - nomoreporn是什么进程 有什么用
  • nodejs ddd
  • Linux base shell重定向详解
  • unity如何成一组
  • 基于unity3d
  • unity3d武器模型
  • android自定义view流程
  • Python常见格式化字符串方法小结【百分号与format方法】
  • 删除的照片怎么还原
  • 登录电子税务局显示时间错误如果解决
  • 国税局云南省税务局
  • 一般纳税人企业所得税怎么算
  • 企业欠税补交后影响贷款吗
  • 银饰品交消费税吗
  • 企业房产税计算器
  • 简易计税方法开的是普票还是专票
  • 云票助手使用步数怎么改
  • 考上如皋地税局好吗
  • 天津摇号申请查询
  • 发票挂失费用
  • 资源税是什么?
  • 重庆房产税每年都交还是交一次
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设