国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Three.js】渲染模型卡頓的優(yōu)化辦法

這篇具有很好參考價(jià)值的文章主要介紹了【Three.js】渲染模型卡頓的優(yōu)化辦法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

事先說(shuō)明

優(yōu)化方法是根據(jù)chatGPT的回答下,我這里記錄一下,有的方法進(jìn)行了嘗試,有的還沒(méi)有。


1、模型面數(shù)過(guò)多導(dǎo)致渲染卡頓

可以通過(guò)減少面數(shù)來(lái)優(yōu)化,也可以使用LOD技術(shù)(Level of Detail)在不同距離下使用不同的模型細(xì)節(jié)來(lái)優(yōu)化。

使用LOD技術(shù)可以在不同距離下使用不同的模型細(xì)節(jié)來(lái)優(yōu)化three.js渲染性能,下面是具體步驟:

  1. 創(chuàng)建多個(gè)模型,每個(gè)模型的面數(shù)和細(xì)節(jié)不同,這些模型應(yīng)該是同一個(gè)對(duì)象的不同版本。

  2. 將這些模型按照從低到高的細(xì)節(jié)順序添加到同一個(gè)LOD(Level of Detail)對(duì)象中,如下所示:

const lod = new THREE.LOD();
const lowDetailModel = ... // 低細(xì)節(jié)模型
const midDetailModel = ... // 中細(xì)節(jié)模型
const highDetailModel = ... // 高細(xì)節(jié)模型
lod.addLevel(lowDetailModel, 0); // 添加低細(xì)節(jié)模型,距離為0
lod.addLevel(midDetailModel, 100); // 添加中細(xì)節(jié)模型,距離為100
lod.addLevel(highDetailModel, 200); // 添加高細(xì)節(jié)模型,距離為200
  1. LOD對(duì)象添加到場(chǎng)景中。
scene.add(lod);
  1. 在渲染循環(huán)中,根據(jù)相機(jī)與LOD對(duì)象的距離,自動(dòng)選擇當(dāng)前需要顯示的模型細(xì)節(jié)等級(jí)??梢允褂?code>THREE.LOD對(duì)象的update方法來(lái)實(shí)現(xiàn)。
function render() {
  requestAnimationFrame(render);
  lod.update(camera);
  renderer.render(scene, camera);
}

2、材質(zhì)貼圖過(guò)大導(dǎo)致渲染卡頓

可以通過(guò)減小貼圖尺寸,壓縮貼圖格式,使用紋理集(Texture Atlas)等方式來(lái)優(yōu)化。

使用紋理集(Texture Atlas)可以將多張小紋理圖合并成一張大紋理圖,從而減少渲染時(shí)的紋理切換次數(shù),優(yōu)化three.js渲染性能,下面是具體步驟:

  1. 創(chuàng)建一張大紋理圖,并將多張小紋理圖拼接在一起,這些小紋理圖應(yīng)該是同一對(duì)象的不同部分,如下所示:
const texture = new THREE.TextureLoader().load('atlas.png');
const material = new THREE.MeshBasicMaterial({ map: texture });
  1. 將每個(gè)物體的UV坐標(biāo)映射到對(duì)應(yīng)的小紋理圖區(qū)域,需要根據(jù)小紋理圖在大紋理圖中的位置和大小計(jì)算出UV坐標(biāo),如下所示:
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);
  // 根據(jù)小紋理圖在大紋理圖中的位置和大小計(jì)算出UV坐標(biāo)
  uvAttribute.setXY(i, u * smallTextureWidth / bigTextureWidth + smallTextureX / bigTextureWidth, v * smallTextureHeight / bigTextureHeight + smallTextureY / bigTextureHeight);
}
  1. 在渲染循環(huán)中,更新大紋理圖的偏移和縮放值。
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、著色器復(fù)雜度過(guò)高導(dǎo)致渲染卡頓

可以通過(guò)簡(jiǎn)化著色器,使用預(yù)編譯的著色器,使用Instancing等方式來(lái)優(yōu)化。

使用Instancing(實(shí)例化)可以將多個(gè)相同的物體復(fù)用同一個(gè)幾何體和材質(zhì),并在渲染時(shí)進(jìn)行一次性繪制,從而減少渲染調(diào)用次數(shù),優(yōu)化three.js渲染性能,下面是具體步驟:

  1. 創(chuàng)建一個(gè)幾何體和材質(zhì),將它們分別作為多個(gè)物體的原型。
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
  1. 創(chuàng)建一個(gè)InstancedBufferGeometry對(duì)象,并將原型幾何體的屬性復(fù)制到它的屬性中。
const instances = 10000; // 實(shí)例數(shù)量
const instancedGeometry = new THREE.InstancedBufferGeometry();
instancedGeometry.copy(geometry); // 復(fù)制幾何體屬性
const translations = new Float32Array(instances * 3); // 實(shí)例位置數(shù)組
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));
  1. 創(chuàng)建一個(gè)InstancedMesh對(duì)象,并將原型材質(zhì)和實(shí)例化幾何體作為它的參數(shù)。
const instancedMesh = new THREE.InstancedMesh(instancedGeometry, material, instances);
scene.add(instancedMesh);
  1. 在渲染循環(huán)中,更新實(shí)例化幾何體的屬性,即實(shí)例的位置、旋轉(zhuǎn)和縮放等信息。
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; // 更新實(shí)例位置屬性
  renderer.render(scene, camera);
}

4、不合理的渲染方式導(dǎo)致渲染卡頓

可以通過(guò)使用合適的渲染方式,如WebGL2渲染,使用Web Worker等方式來(lái)優(yōu)化。

Ⅰ、使用WebGL2可以在現(xiàn)代瀏覽器中利用新的圖形處理能力,優(yōu)化three.js渲染性能,下面是具體步驟:
① 在渲染器中啟用WebGL2。

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

② 使用WebGL2支持的新特性,如transform feedback、instanced arrays等。
例如,以下代碼演示了如何使用transform feedback來(lái)記錄頂點(diǎn)位置的變化:

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: {
    // 將頂點(diǎn)位置記錄到transformedPosition變量中
    varyings: ['transformedPosition'],
    // 開(kāi)啟transform feedback
    enabled: true,
    // 設(shè)置bufferGeometry的位置屬性為transform feedback的輸出屬性
    bufferGeometry: bufferGeometry
  }
});
const mesh = new THREE.Mesh(bufferGeometry, shader);
scene.add(mesh);
function render() {
  requestAnimationFrame(render);
  renderer.setRenderTarget(null);
  // 開(kāi)始transform feedback
  transformFeedback.begin();
  renderer.render(scene, camera);
  // 結(jié)束transform feedback,并將變化后的頂點(diǎn)位置存儲(chǔ)到bufferGeometry中
  transformFeedback.end();
  // 更新頂點(diǎn)位置
  positions.set(bufferGeometry.getAttribute('position').array);
  bufferGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  renderer.render(scene, camera);
}

---------------------------------------------------------------分隔線-----------------------------------------------------------------


Ⅱ、使用Web Worker可以將計(jì)算密集型的任務(wù)分離到另一個(gè)線程中,從而避免主線程被阻塞,優(yōu)化three.js渲染性能,下面是具體步驟:

① 創(chuàng)建一個(gè)Web Worker,用于處理計(jì)算密集型的任務(wù)。

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

② 在Web Worker中定義處理函數(shù)。

// worker.js
function process(data) {
  // 計(jì)算密集型的任務(wù)
  return result;
}
onmessage = function(event) {
  const result = process(event.data);
  postMessage(result);
};

③ 在主線程中將任務(wù)發(fā)送到Web Worker,并設(shè)置回調(diào)函數(shù)處理返回結(jié)果。

function render() {
  requestAnimationFrame(render);
  // 發(fā)送任務(wù)到Web Worker
  worker.postMessage(data);
  worker.onmessage = function(event) {
    const result = event.data;
    // 處理返回結(jié)果
  };
  renderer.render(scene, camera);
}

通過(guò)以上步驟,就可以使用Web Worker來(lái)將計(jì)算密集型的任務(wù)分離到另一個(gè)線程中,從而避免主線程被阻塞,優(yōu)化three.js渲染性能。需要注意的是,Web Worker中無(wú)法直接訪問(wèn)主線程的DOM和three.js對(duì)象,需要通過(guò)消息傳遞來(lái)實(shí)現(xiàn)通信。


5、CPU和GPU資源不平衡導(dǎo)致渲染卡頓

可以通過(guò)分析性能監(jiān)控,優(yōu)化代碼邏輯,使用requestAnimationFrame等方式來(lái)平衡CPU和GPU資源占用。

使用requestAnimationFrame可以讓瀏覽器根據(jù)自身的渲染節(jié)奏調(diào)整動(dòng)畫(huà)的幀率,從而避免過(guò)度渲染,優(yōu)化three.js渲染性能,下面是具體步驟:

  1. 將渲染函數(shù)作為requestAnimationFrame的回調(diào)函數(shù)。
function render() {
  // 渲染代碼
  renderer.render(scene, camera);
  // 請(qǐng)求下一幀動(dòng)畫(huà)
  requestAnimationFrame(render);
}
  1. 在初始化時(shí)調(diào)用一次requestAnimationFrame,啟動(dòng)動(dòng)畫(huà)。
var animationId = requestAnimationFrame(render);
  1. 在動(dòng)畫(huà)結(jié)束時(shí),記得停止requestAnimationFrame,以避免不必要的資源消耗。
function stop() {
  cancelAnimationFrame(animationId);
}

需要注意的是,使用requestAnimationFrame時(shí)需要避免在渲染循環(huán)中進(jìn)行過(guò)多的計(jì)算,以免影響渲染性能。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-446357.html

到了這里,關(guān)于【Three.js】渲染模型卡頓的優(yōu)化辦法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Three.js初識(shí):渲染立方體、3d字體、修改渲染背景顏色

    Three.js初識(shí):渲染立方體、3d字體、修改渲染背景顏色

    用場(chǎng)景對(duì)three.js進(jìn)行渲染:場(chǎng)景、相機(jī)、渲染器 場(chǎng)景 透視攝影機(jī) 參數(shù)解析: fov: 視野角度(FOV)。視野角度就是無(wú)論在什么時(shí)候,你所能在顯示器上看到的場(chǎng)景的范圍,它的單位是角度(與弧度區(qū)分開(kāi))。 aspect: 長(zhǎng)寬比(aspect ratio)。 也就是你用一個(gè)物體的寬除以它的高的值

    2024年02月07日
    瀏覽(25)
  • 基于Three.js的WebXR渲染入門(mén)

    基于Three.js的WebXR渲染入門(mén)

    我不會(huì)花太多時(shí)間討論 Three.JS 渲染管道的工作原理,因?yàn)樗诨ヂ?lián)網(wǎng)上有詳細(xì)記錄(例如,此鏈接)。 我將在下圖中列出基礎(chǔ)知識(shí),以便更容易理解各個(gè)部分的去向。 在我們深入了解 WebXR API 本身之前,您應(yīng)該知道 WebXR 設(shè)備 API Polyfill 可通過(guò)兩種主要方式幫助開(kāi)發(fā)人員: 如

    2024年02月11日
    瀏覽(22)
  • 多個(gè)數(shù)據(jù)webSocket推送太快導(dǎo)致前端渲染卡頓問(wèn)題優(yōu)化

    作者代碼寫(xiě)的不怎么樣,諒解!主要思路就是把websocket接收到的數(shù)據(jù)用一個(gè)數(shù)組暫存起來(lái),達(dá)到一定數(shù)量一起修改統(tǒng)一渲染,可根據(jù)項(xiàng)目數(shù)據(jù)推送數(shù)據(jù)的速度適當(dāng)調(diào)解數(shù)組大小,然后再加了一個(gè)可能一段時(shí)間內(nèi)都到不到數(shù)組達(dá)標(biāo)渲染數(shù)量,就使用定時(shí)器直接做渲染,防止數(shù)據(jù)

    2024年02月12日
    瀏覽(27)
  • Three.js教程:WebGL渲染器設(shè)置(鋸齒模糊)

    推薦:將 NSDT場(chǎng)景編輯器 加入你的3D工具鏈 其他系列工具: NSDT簡(jiǎn)石數(shù)字孿生 一般實(shí)際開(kāi)發(fā),threejs的WebGL渲染器需要進(jìn)行一些通用的基礎(chǔ)配置,本節(jié)課給大家簡(jiǎn)單介紹下,比如渲染模糊或鋸齒問(wèn)題。 渲染器鋸齒屬性 .antialias 設(shè)置渲染器鋸齒屬性 .antialias 的值可以直接在參數(shù)中

    2024年02月11日
    瀏覽(86)
  • Three.js之相機(jī)、渲染器、光源、動(dòng)畫(huà)、性能監(jiān)測(cè)

    第一個(gè)3D案例—透視投影相機(jī) 第一個(gè)3D案例—渲染器 … Canvas畫(huà)布布局和全屏 透視投影相機(jī)PerspectiveCamera WebGL渲染器WebGLRenderer 輔助觀察坐標(biāo)系A(chǔ)xesHelper 漫反射網(wǎng)格材質(zhì)MeshLambertMaterial 點(diǎn)光源PointLight 點(diǎn)光源輔助觀察PointLightHelper 環(huán)境光AmbientLight 平行光DirectionalLight 平行光輔助觀

    2024年02月13日
    瀏覽(27)
  • 【Three.js基礎(chǔ)】創(chuàng)建場(chǎng)景、渲染場(chǎng)景、創(chuàng)建軌道控制器(一)

    【Three.js基礎(chǔ)】創(chuàng)建場(chǎng)景、渲染場(chǎng)景、創(chuàng)建軌道控制器(一)

    ?? 個(gè)人主頁(yè): 不叫貓先生 ???♂? 作者簡(jiǎn)介:前端領(lǐng)域新星創(chuàng)作者、阿里云專(zhuān)家博主,專(zhuān)注于前端各領(lǐng)域技術(shù),共同學(xué)習(xí)共同進(jìn)步,一起加油呀! ??系列專(zhuān)欄:vue3從入門(mén)到精通、TypeScript從入門(mén)到實(shí)踐 ?? 資料領(lǐng)取:前端進(jìn)階資料以及文中源碼可以找我免費(fèi)領(lǐng)取 ?? 前端

    2024年02月01日
    瀏覽(95)
  • Three.js之幾何體、高光材質(zhì)、渲染器設(shè)置、gui

    陣列立方體和相機(jī)適配體驗(yàn) Threejs常見(jiàn)幾何體簡(jiǎn)介 … gui.js庫(kù)(可視化改變?nèi)S場(chǎng)景) 注:基于Three.js v0.155.0 長(zhǎng)方體:BoxGeometry 球體:SphereGeometry 圓柱:CylinderGeometry 矩形平面:PlaneGeometry 圓形平面:CircleGeometry 高光網(wǎng)格材質(zhì):MeshPhongMaterial(shininess、specular) WebGL渲染器設(shè)置:

    2024年02月11日
    瀏覽(28)
  • three js模型旋轉(zhuǎn)

    three js模型旋轉(zhuǎn)

    如何讓立方體模型旋轉(zhuǎn)到指定的面 父頁(yè)面 效果:

    2024年02月15日
    瀏覽(34)
  • Three.js 三維模型(一)

    Three.js 三維模型(一)

    今天主要給搭建介紹下three.js的基本使用,本篇是基于筆者在16年給做的一個(gè)項(xiàng)目的demo版進(jìn)行講解的,筆者當(dāng)時(shí)采用Html5和JS進(jìn)行編寫(xiě)的??赡艽蠹視?huì)問(wèn)有沒(méi)有vue、React 、angular版的。這些筆者后面有時(shí)間的時(shí)候一定會(huì)給大家介紹。 其實(shí)編程的本源在于提煉屬于自己的哲學(xué)思想

    2024年02月16日
    瀏覽(36)
  • three.js添加3d模型

    three.js添加3d模型

    three官方的幾何體也就那么幾個(gè),想要生成各種各樣的模型,其難度十分之大,這時(shí)引入外部模型也不失為一種選擇。具體引入辦法如下。 雖然名字為GLTFLoader,但實(shí)際上glb文件也是能加載的。 其中需要注意的是調(diào)節(jié)相機(jī)參數(shù)與相機(jī)位置,否則很有可能導(dǎo)致場(chǎng)景中看不見(jiàn)任何東

    2024年02月04日
    瀏覽(104)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包