偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

擁抱新一代 Web 3D 引擎,Three.js 項(xiàng)目快速升級(jí) Galacean 指南

開(kāi)發(fā) 前端
本文從多個(gè)維度對(duì)比 Galacean 和 Three.js 兩款Web3D 引擎的差異,并介紹擬我形象項(xiàng)目從Three.js 切換到 Galacean 以后帶來(lái)的提升以及項(xiàng)目遷移的心得,為其他 Three.js 項(xiàng)目升級(jí)到 Galacean 提供參考。

01、背景

Web 3D 技術(shù)的發(fā)展日新月異,為我們帶來(lái)了前所未有的沉浸式體驗(yàn)。從虛擬展示到游戲開(kāi)發(fā),從建筑可視化到教育模擬,Web 3D 技術(shù)的應(yīng)用場(chǎng)景愈發(fā)廣泛。而在這一領(lǐng)域,Three.js 作為一款廣受歡迎的 JavaScript 3D 庫(kù),憑借其簡(jiǎn)潔易用的 API 和豐富的功能,幫助眾多開(kāi)發(fā)者實(shí)現(xiàn)了精彩的 3D 項(xiàng)目。

然而,隨著項(xiàng)目復(fù)雜度的不斷提升,以及用戶對(duì)性能和體驗(yàn)要求的日益苛刻,Three.js 逐漸顯露出一些局限性。比如在處理重負(fù)載時(shí),很容易遇到性能瓶頸,出現(xiàn)卡頓、掉幀等問(wèn)題。這就如同一位經(jīng)驗(yàn)豐富的車手,駕駛著一輛曾經(jīng)性能卓越的賽車,但在面對(duì)愈發(fā)復(fù)雜的賽道和激烈的競(jìng)爭(zhēng)時(shí),卻發(fā)現(xiàn)車輛的動(dòng)力和操控性漸漸力不從心。

02、Galacean:新一代 Web 3D 引擎

2.1業(yè)務(wù)簡(jiǎn)介

擬我形象是 vivo 賬號(hào)中的一個(gè)3D數(shù)字人功能,提供一種代表自由、個(gè)性、創(chuàng)新和時(shí)尚的虛擬形象,為用戶提供更加生動(dòng)、直觀、有趣的交流方式。采用 Native+H5混合的開(kāi)發(fā)方式,其中 3D 渲染的部分基于 Three.js 進(jìn)行開(kāi)發(fā)。

2.2技術(shù)挑戰(zhàn)與痛點(diǎn)

  • 性能瓶頸:人物模型包含大量形態(tài)鍵以實(shí)現(xiàn)多樣化面部特征,導(dǎo)致模型加載解析耗時(shí)過(guò)長(zhǎng)。
  • 線程阻塞:受限于JS單線程特性,模型解析過(guò)程會(huì)造成頁(yè)面短暫無(wú)響應(yīng)。
  • 多模型渲染:套裝切換等場(chǎng)景下,多個(gè)模型同時(shí)渲染時(shí)性能問(wèn)題尤為突出。
  • 陰影優(yōu)化:Three.js 的陰影渲染性能消耗大,不得不通過(guò)局部陰影和限制捕捉范圍等折中方案來(lái)平衡畫(huà)質(zhì)與性能。

2.3Galacean 引擎核心優(yōu)勢(shì)

Galacean 是一款開(kāi)源的 Web 游戲引擎,致力于打造一個(gè)開(kāi)放、易用、高效的游戲開(kāi)發(fā)工具,可以通過(guò)在線編輯器或者純代碼的形式進(jìn)行使用。

針對(duì)現(xiàn)存的技術(shù)挑戰(zhàn)與痛點(diǎn),Galacean做了深度優(yōu)化:

  • 多線程處理:采用Worker避免主線程阻塞。
  • 移動(dòng)端適配:對(duì)大量常量進(jìn)行近似取值優(yōu)化,完美適配移動(dòng)端。
  • 性能突破:優(yōu)化數(shù)據(jù)傳輸鏈路,創(chuàng)新緩存設(shè)計(jì),顯著降低重負(fù)載場(chǎng)景下的卡頓現(xiàn)象。

此外,Galacean 基于 EC(Entity-Component)架構(gòu)設(shè)計(jì),而非 Three.js 的面向?qū)ο?,大幅提升了開(kāi)發(fā)的靈活性。

近期我們將渲染引擎由 Three.js 切換為 Galacean。這一舉措不僅解決了頁(yè)面卡頓問(wèn)題,還提升了瀏覽器兼容性(可支持到 chrome82),幀率表現(xiàn)更出色,畫(huà)面質(zhì)感也得到顯著改善。整體切換過(guò)程較為平滑,但也遇到了一些問(wèn)題。接下來(lái),將與大家分享此次整體升級(jí)的相關(guān)經(jīng)驗(yàn)。

03、調(diào)優(yōu)過(guò)程

任務(wù)拆解:

作為一個(gè)數(shù)字人項(xiàng)目,涉及到引擎升級(jí)的模塊大致有

①環(huán)境初始化(場(chǎng)景、相機(jī)、光線、引擎設(shè)置)

② 模型加載

  • 骨架獲取
  • 材質(zhì)獲取
  • 動(dòng)畫(huà)獲取

③妝容、穿搭還原

  • 形態(tài)鍵修改
  • 貼圖、顏色修改
  • 模型替換
  • 頭像(靜態(tài)頭像、動(dòng)態(tài)頭像)導(dǎo)出
  • 壁紙(靜態(tài)壁紙、動(dòng)態(tài)壁紙、視差壁紙)導(dǎo)出

經(jīng)過(guò)梳理,可以大致分為四類:

  • 初始化
  • 模型加載
  • 素材替換
  • 動(dòng)畫(huà)狀態(tài)

接下來(lái)我們對(duì)這幾個(gè)部分進(jìn)行分別的處理

3.1初始化

有別于 Three.js 的渲染器創(chuàng)建,Galacean 的 engine 初始化是異步方法,所以后續(xù)用到用到engine的地方需要考慮加載的時(shí)序,以及engine存在狀態(tài)的判斷。另外,Three.js 中 renderer 的渲染行為需要手動(dòng)調(diào)用,一般是使用requestAnimationFrame循環(huán)調(diào)用,而Galacean則不需要,引擎開(kāi)始渲染只需要調(diào)用一次 engine.run 即可。

const renderer=new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
})
document.body.appendChild(renderer.domElement)
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(15, window.innerWidth/window.innerHeight, 0.1, 100)
requestAnimationFrame(function render() {
  renderer.render(scene, camera)
  requestAnimationFrame(render)
})
const engine = await WebGLEngine.create({
  canvas,
  physics: new LitePhysics()
})
engine.run()

在 Three.js 中,尺寸單位統(tǒng)一以米為基準(zhǔn),無(wú)需額外進(jìn)行特殊處理。不過(guò)在角度單位的使用上存在差異:Three.js 里,僅相機(jī)的 fov(視場(chǎng)角)采用角度單位,其他涉及角度的參數(shù)均以弧度計(jì)量;而 Galacean 則采用更為統(tǒng)一的設(shè)定,所有角度相關(guān)單位均為角度。

/** Three.js */
camera.fov = 15
item.rotation.y = 15 * Math.PI/180


/** Galacean */
camera.fieldOfView = 15
item.rotation.y = 15

在Three.js中顏色的設(shè)置更加靈活,可以使用16進(jìn)制或者RGB值來(lái)進(jìn)行賦值,但是在Galacean中只能通過(guò)RGB來(lái)進(jìn)行賦值,且有別于0-255的取值范圍,Galacean中的顏色范圍是0-1。從Galacean1.5版本開(kāi)始,默認(rèn)的色彩空間改為線性,在代碼中需要手動(dòng)轉(zhuǎn)換一下。

/** Three.js */
directLight.color=0xffffff
directLight.intensity=0.9


/** Galacean */
const color = new Color(0.9, 0.9, 0.9, 1)
color.toLinear(color)
directLight.color = color

3.2模型加載

對(duì)于包含大量形態(tài)鍵和動(dòng)畫(huà)的模型,將模型打成zip包可以有效的壓縮模型的體積,不論是Three.js還是Galacean都不支持加載zip包,但是我們可以自行擴(kuò)展模型加載的鏈路,將zip下載后解壓出的模型獲取ObjectUrl再放到各自的加載器中加載,這樣加載進(jìn)度的獲取也可以進(jìn)行自定義,不需要進(jìn)行額外的改造。

exportclassModelLoader {
  engine: WebGLEngine
  constructor(engine: WebGLEngine){
    this.engine = engine
  }
  async load(src: string) {
    const url = await fileLoader(src)
    returnthis.engine.resourceManager.load<GLTFResource>({
      url,
      type: AssetType.GLTF
    })
  }
}

Three.js 解析 glTF 模型輸出的數(shù)據(jù)結(jié)構(gòu)較為簡(jiǎn)單,主要使用模型的場(chǎng)景和動(dòng)畫(huà)片段。由于后續(xù)需針對(duì)特定材質(zhì)進(jìn)行替換,所以要根據(jù)節(jié)點(diǎn)名獲取特定節(jié)點(diǎn),再取出節(jié)點(diǎn)中的材質(zhì)信息,模型的骨架也通過(guò)這種方式獲取。而 Galacean 輸出的數(shù)據(jù)更為全面,除動(dòng)畫(huà)片段和實(shí)體信息外,模型中使用的材質(zhì)、貼圖、蒙皮和網(wǎng)格信息也會(huì)分門(mén)別類展示,需要對(duì)應(yīng)內(nèi)容時(shí)直接獲取即可,相比 Three.js 更加方便。

3.3素材替換

素材替換如上文總結(jié)分為四種,分別是顏色、貼圖、形態(tài)鍵和模型的替換,顏色設(shè)置我們?cè)诔跏蓟幸呀?jīng)講解,而模型加載和展示也沒(méi)有特別的內(nèi)容,無(wú)非是節(jié)點(diǎn)/實(shí)體的添加和移除,這里我們講下貼圖和形態(tài)鍵修改的一些tips。

在Three.js中修改材質(zhì)貼圖map可以直接直接使用canvas或者image,修改后需要將材質(zhì)needsUpdate屬性設(shè)置為true。而在Galacean需要先將圖片加載為texture,再進(jìn)行賦值。

/** Three.js */
material.map=canvas
material.needsUpdate = true


/** Galacean */
const texture: Texture2D = await engine.resourceManager.load({
  url,
  type: AssetType.Texture2D
})
material.baseTexture = texture

在Three.js中修改形態(tài)鍵,可以先通過(guò)網(wǎng)格中的morphTargetDictionary屬性獲取到需要修改的形態(tài)鍵的索引,然后修改morphTargetInfluences中對(duì)應(yīng)索引的值即可。

在Galacean中網(wǎng)格渲染器中沒(méi)有存儲(chǔ)形態(tài)鍵的索引信息,而是存儲(chǔ)在MeshRenderer下的mesh屬性下的blendShapes屬性中,通過(guò)獲取對(duì)應(yīng)名稱的形態(tài)鍵在數(shù)組中的索引,修改網(wǎng)格渲染器中blendShapeWeights屬性對(duì)應(yīng)下標(biāo)的值。

/** Three.js */
const index = morphTargetDictionary[keyName]


if (index !== undefined) {
  mesh.morphTargetInfluences[index] = value
}


/** Galacean */
const blendShapes = skinMeshRenderer.mesh.blendShapes
const index = blendShapes.findIndex(i=>i.name===keyName)
if (index > -1){
  skinMeshRenderer.blendShapeWeights[index] = value
}

3.4動(dòng)畫(huà)

相較于Three.js的AnimationMixer和AnimationClip,Galacean擁有更加完善的面向組件的動(dòng)畫(huà)系統(tǒng),支持 狀態(tài)機(jī)、混合動(dòng)畫(huà)、時(shí)長(zhǎng)壓縮等,不同動(dòng)畫(huà)之間的切換與播放更加簡(jiǎn)單易維護(hù)。

/** Three.js 播放動(dòng)畫(huà)片段 */
const mixer = new THREE.AnimationMixer(scene)
const actinotallow=mixer.clipAction(avatarClip)
action.play()
ticker.addEvent(delta => {
  mixer.update(delta)
})


/** Galacean 添加狀態(tài)機(jī),播放完成回到待機(jī)狀態(tài) */
const animationState = animator.findAnimatorState('action')
const idleStatle = animator.findAnimatorState('idle')
const transition = new AnimatorStateTransition()
transition.duration = 1
transition.offset = 0
transition.exitTime = 1
transition.destinationState = idleStatle
animationState.addTransition(transition)
animator.play('action')

04、結(jié)語(yǔ)

Galacean 的出現(xiàn),無(wú)疑為 Web 3D 開(kāi)發(fā)領(lǐng)域帶來(lái)了新的活力。它不僅解決了 Three.js 等傳統(tǒng)技術(shù)在性能和功能上的諸多痛點(diǎn),還以其卓越的性能、豐富的功能和易用性,為開(kāi)發(fā)者打開(kāi)了一扇通往更廣闊創(chuàng)意空間的大門(mén)。

需要注意的是,Galacean不同版本之間的API差異較大,需要進(jìn)行甄別,同時(shí)開(kāi)發(fā)文檔及相關(guān)的案例也需要進(jìn)一步完善。

對(duì)于全新的項(xiàng)目,Galacean提供編碼或在線編輯器兩種方式保障創(chuàng)意的高效落地,詳細(xì)的文檔和案例也便于接觸 Web3D 開(kāi)發(fā)的新人快速上手。

對(duì)于存量的項(xiàng)目,Galacean的遷移成本不高,且整個(gè)過(guò)程平滑可控,能夠有效提升現(xiàn)有項(xiàng)目的畫(huà)面表現(xiàn)和性能。為未來(lái)復(fù)雜度更高的需求提供性能保障。

責(zé)任編輯:龐桂玉 來(lái)源: vivo互聯(lián)網(wǎng)技術(shù)
相關(guān)推薦

2019-11-29 09:30:37

Three.js3D前端

2024-07-18 06:58:36

2023-07-13 10:48:22

web 3DThree.jsBlender

2022-01-16 19:23:25

Three.js粒子動(dòng)畫(huà)群星送福

2025-03-17 10:38:30

2021-11-23 22:50:14

.js 3D幾何體

2012-07-25 13:19:16

ibmdw

2014-10-24 14:10:50

高德導(dǎo)航

2021-07-15 11:16:31

Spring WebWebFlux架構(gòu)

2021-11-27 10:42:01

Three.js3D可視化AudioContex

2023-03-09 14:21:12

字節(jié)跳動(dòng)云固件

2009-06-25 17:14:59

JSF框架

2025-06-30 09:15:47

2022-06-01 06:06:28

Web 3元宇宙數(shù)字化

2016-06-01 09:19:08

開(kāi)發(fā)3D游戲

2021-04-21 09:20:15

three.js3d前端

2012-07-02 10:36:19

菲亞特

2022-03-10 16:01:29

Playwright開(kāi)源

2022-07-15 13:09:33

Three.js前端

2016-01-26 11:58:12

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)