具體涉及到的知識點如下:
天空球
霧化
輝光
景深
這是最終效果:
天空球:
天空球(SkyBox)簡單來說,就是用來在3D場景中模擬藍天白云的效果。它是一個球形網格,完全包圍3D場景,并填充了一張環形紋理作為天空背景。紋理通常是一個天空的全景圖(例如星空、日落、云層等),通過在球形網格的表面上將紋理映射,呈現出一個連續的、無縫的天空效果。
在 HT for Web中,天空球可以通過g3d.setSkybox(node)來實現。需要注意的是,這里的node是ht.Node類型的節點,該節點當作天空球來用時,不會出現在dataModel列表當中。
/** * 設置天空球 * * @memberof Index3d */ addSkybox() { const node = this.skybox = new ht.Node(); node.s({ "shape3d": "sphere", "shape3d.image": "./assets/skybox.jpg", }); this.g3d.setSkybox(node); }
下面兩張圖片分別是設置天空球與未設置天空球的效果:
當然,我們也可以將藍天白云換成夜間圖片:
this.skybox.setStyle("shape3d.image", "./assets/skybox_dark.jpg");
霧化:
霧化是一種常用的 3D 場景效果,可以讓場景中的物體在遠離攝像機的距離時變得模糊,像有一層白霧遮擋,從而增加深度感和真實感。在 HT 中,霧化效果可以通過設置場景的霧化屬性來實現,代碼如下:
/** * 霧化 * * @memberof Index3d */ addFog() { this.g3d.setFogDisabled(false); this.g3d.setFogMode('linear'); // 線性模式 this.g3d.setFogFar(30000); // this.g3d.setFogMode('exp2'); // 標準模式 // this.g3d.setFogDensity(0.00007); // 濃度 this.g3d.setFogColor('green'); // 設置霧的顏色 }
霧化分為兩種模式:線性模式和標準模式。
[線性模式]
線性模式下支持設置近端距離和遠端距離,
近端距離:默認為1,代表從該距離起物體開始受霧效果影響,可通過setFogNear設置霧化近端距離、getFogNear獲取霧化近端距離。
遠端距離:默認為2000,代表從該距離之后物體完全看不清, 可通過setFogFar設置霧化遠端距離、getFogFar獲取霧化遠端距離。
[標準模式]
標準模式下霧化效果則會自動調整霧化效果,在該模式下,可通過setFogDensity設置霧化強度來調整霧化的效果, getFogDensity可以獲取到霧化強度。
另外,我們還可通過g3d.setFogColor(color)設置霧化效果的顏色:
輝光:
輝光是一種用于增強場景中元素外觀和吸引力的視覺效果,其主要實現的是讓各個模型進行自發光。常用于如夜景中燈光、道路流光等元素。
在HT中,可通過 g3d.enablePostProcessing('Bloom', true/false) 開啟/關閉整個場景的輝光效果:
/** * 開啟輝光 * * @memberof Index3d */ enableBloom() { const {g3d} = this; g3d.enablePostProcessing("Bloom", true); // 開啟輝光 const module = this.bloom = g3d.getPostProcessingModule("Bloom"); module.strength = 0.4; // 強度 module.threshold = 0.33; // 閾值 module.radius = 0.08; //范圍 g3d.setPostProcessingValue('Bloom', 'selective', true); // 開啟輝光過濾 g3d.iv(); // 刷新拓撲 } disableBloom() { this.g3d.enablePostProcessing("Bloom", false); // 關閉輝光 } // 為直升機單獨使用輝光效果 this.helicopterNode.s('bloom', true);
this.propellerNode.s('bloom', true);
其中,enablePostProcessing('Bloom', true)表示開啟 Bloom 效果;strength表示自發光亮度的強弱;threshold表示決定哪些顏色會發光;radius表示發光的范圍。在代碼的后半段,我們單獨為直升機和螺旋槳開啟了輝光效果。
景深:
景深(Depth of Field)可以用來突出畫面中的主體元素。我們用單反相機或手機進行拍攝時,利用景深原理,通過聚焦到某一物體,可以使周圍環境變得模糊,從而突出主要元素。就像下圖一樣:
如果要對于一個3D場景設置景深效果,在 HT 中,景深效果是使用特殊的貼圖來模擬的。景深貼圖一般使用黑色的透明png貼圖實現,黑色部分為受景深影響的范圍,透明部分不受景深影響。通過使用不同的景深貼圖及參數,可以模擬出與現實一樣的景深效果。
具體開啟和配置景深的代碼如下:
/** * 開啟景深 * * @memberof Index3d */ enableDof() { const {g3d} = this; g3d.enablePostProcessing("Dof", true); // 開啟景深 const module = this.dof = g3d.getPostProcessingModule("Dof"); module.aperture = 0.01; // 景深閥值 module.image = "./assets/dof_all.png"; // 景深貼圖 g3d.iv(); // 刷新拓撲 } disableDof() { this.g3d.enablePostProcessing("Dof", false); // 關閉景深 }
其中,enablePostProcessing('Dof', true)表示開啟景深效果;aperture表示孔徑,代表中間空白區域的大小,取值范圍是 0 ~ 1,0 代表沒有景深效果,1 代表景深效果最明顯;image表示景深使用的貼圖。
背景音樂
背景音樂不屬于3D可視化的范圍。不過既然有了直升機和相關場景,增加一個直升機飛行的聲音可以讓場景更加逼真。
/** * 初始化螺旋槳旋轉聲音 * * @memberof Index3d */ initAudio() { this._audio = new Audio("./assets/helicopter.MP3"); this._audio.loop = true; // 循環播放 }
要播放音樂可以使用Audio。這里我們只需要找到一個螺旋槳的音頻,然后對Audio進行初始化及簡單配置,就可以在場景加載后循環播放直升機的聲音。
需要注意的是,目前瀏覽器對于音頻自動播放有限制,即不允許在用戶沒有交互的情況下自動播放音頻文件。如果我們執行了playAudio(),在console里面會遇到這個錯誤:
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
要解決這個問題,我們可以在系統中增加一個監聽函數,監聽到某些事件后進行音頻播放。常見的事件有如:
觸摸事件:touchstart、touchmove、touchend、touchcancel
鼠標事件:mousedown、mouseup、click、dblclick、mousemove、mouseenter、mouseleave、mouseover、mouseout
鍵盤事件:keydown、keyup、keypress
/** * 監聽Document事件并播放音樂 * * @memberof Index3d */ addEventMonitor() { document.addEventListener("click", (event) => { this._audio.play(); }); document.addEventListener("keydown", (event) => { this._audio.play(); }); }
總結
作為一款國產自研圖形渲染引擎,HT for Web對3D場景的各自效果支持還是非常強大的。在3D場景(Graph3dView)中,可以通過設置天空球、霧化、輝光和景深等特效來增強場景的逼真度和美觀度。其中,天空球可以通過設置ht.Node類型的節點來實現,霧化可以通過設置場景的霧化屬性來實現,輝光可以使用g3d.enablePostProcessing()方法來實現,景深可以使用特殊的貼圖來模擬。此外,為了讓場景更加逼真,還可以根據需要添加背景音樂。
審核編輯 黃宇
-
3D
+關注
關注
9文章
2910瀏覽量
107799 -
數字孿生
+關注
關注
4文章
1342瀏覽量
12316
發布評論請先 登錄
相關推薦
評論