2017-10-19 172 views
0

我遇到的問題是當我有一個網格,其中只有網格的一些面應該是半透明的,而對象的其餘部分應該是不透明的。任何人都知道我應該如何解決這個問題?如何渲染部分半透明的網格?

下面是對這個問題的更多描述:清晰度:在我們的瀏覽器中,如果它們具有相同的材質屬性,我們會合並多個網格物體。

然後,如果用戶點擊合併對象,我們會發現被點擊的表面和該面部對象的原始ID。然後,我們只用我們自己的自定義着色器突出顯示該對象的面部。

一個對象選擇
one object selected

現在的問題是,如果我們使材料透明的(因此所選擇的部分是半透明的),則整個合併的網格是透明的,該模型的不透明部分被呈現透明。

你可以看到一些視覺問題,在這樣的畫面:

視覺問題的部分透明的對象
visual issues for partially transparent object

我對我們如何能夠解決這個問題,但他們都將增加存儲多思路消耗和複雜度:

  1. 丟棄應該是透明的碎片,然後用選定的面和透明材質創建一個新的網格。

  2. 創建一個透明的整個合併網格的副本,然後只渲染透明對象中的選定對象面並丟棄原始非透明網格中的片段。

任何人都有更好的主意嗎?

使用三個r84。

+0

你對所有的盒子都有'.transparent = true'嗎? – prisoner849

+0

所有的盒子都是這個例子中的一個網格,所以通過設置材質爲透明的,所以我可以顯示一些透明的面孔,這樣所有的盒子都是透明的。 – Krigsdal

+1

使用深度剝離你可以實現你想要的,但我認爲three.js本身並不實現它。我認爲你的最佳策略是將你的「分組網格」分成幾個網格,並獨立處理每個「盒子」。透明度在3D渲染中從來不是一個微不足道的問題。 – 2017-10-19 09:39:29

回答

0

我不明白爲什麼你不想使用分離的盒子網格,因爲它更容易管理每個網格的透明度。

但是,如果你想使用單一的幾何,我想出了一種使用兩種材料,.materialIndex和動態幾何的方法。該方法依賴於this SO answer

var materials = [ 
    new THREE.MeshLambertMaterial({ color: "white" }), 
    new THREE.MeshLambertMaterial({ color: "white", transparent: true, opacity: 0.5}) 
]; 

. . . 

var cloneGeom = new THREE.Geometry(); 

var oldBoxIndex = 0; 

function setBoxTransparent(boxIndex) { 
    cloneGeom = mesh.geometry.clone(); 
    setBoxMaterial(oldBoxIndex, 0); 
    setBoxMaterial(boxIndex, 1); 
    mesh.geometry.dispose(); 
    mesh.geometry = cloneGeom; 
    oldBoxIndex = boxIndex; 
} 

function setBoxMaterial(boxIndex, materialIndex) { 
    for (let i = 0; i < 12; i++) { 
    cloneGeom.faces[12 * boxIndex + i].materialIndex = materialIndex; 
    } 
} 

jsfiddle例子r87。

+0

因爲分離的盒子網格意味着,而不是有1個網格= 1繪製電話,你將有50k盒子= 50 000繪製電話,這將意味着非常低的FPS,或者我誤解你的意思?此外,我使用BufferGeometry和customShaders,所以我將不得不適應它來使用它。即使使用materialIndex,它也會增加渲染調用的次數,因爲如果我正確理解渲染函數,每個組都會被調用一次,但它只會對所選對象進行雙重渲染調用。感謝您抽出寶貴的時間和精力仔細查看使用團體是否可以工作! – Krigsdal

+0

不客氣)但是你應該提到在你的問題中有超過5萬個盒子(或場景的複雜性)和自定義着色器)而是,你只展示一個只有256個盒子的圖片,這並不是什麼大不了的) – prisoner849

+1

是的,你說得對::)我用這些框來容易地展示這個概念,但它的真正應用是大型的CAD模型。 – Krigsdal