2013-01-03 18 views
17

我有大量(〜1000)THREE.Mesh對象,它們是由相同的THREE.GeometryTHREE.MeshPhongMaterial(它有一張圖)構建而成的。許多具有相同幾何和材質的網格,我可以改變它們的顏色嗎?

我想單獨着色(彩色)這些對象。簡單地說,我試着改變mesh.material.color屬性,但是在任何對象上改變這個屬性都會立刻改變所有對象的顏色。這是有道理的,因爲只有一種材料在所有對象之間共享。

我的下一個想法是爲每個對象創建一個單獨的THREE.MeshPhongMaterial。所以,現在我有大量的THREE.Mesh對象,它們是由相同的THREE.Geometry構建而成的,但它們有個別的THREE.MeshPhongMaterials(它們具有相同的紋理)。這使我可以單獨更換顏色,但性能更差。 Chrome profilier表明該應用程序正在花費大量時間處理材質切換紋理等事情。

材質顏色在着色器中只是一個統一。所以,更新制服應該很快。

問題:有沒有一種方法來覆蓋網格級別的材質顏色?

如果有的話,我相信我可以在我的所有物品中分享材質,並讓我的表演迴歸,同時仍然單獨更改顏色。

[我已在V49和V54測試,它們具有相同的性能和降解]

更新:我建立了一個測試的情況下,並且由於這種性能降比我認爲這是較小的,但仍然可以衡量。

這裏有兩個環節:

在第一種情況下,只有兩種材料,在第二種情況下每個立方體都有它自己的材料。我在這臺機器上測量第一種情況的幀率爲53fps,第二種情況的幀率爲46fps。這大約下降15%。

在這兩種情況下,每個立方體的材質顏色都會每幀更改一次。在許多材料的情況下,我們實際上看到每個立方體獲得它自己的顏色,在僅有兩種材料的情況下,我們看到它們都具有相同的顏色(如預期的那樣)。

+2

呃,這聽起來像一個「bug」。如果你可以用r54重現問題,那麼如果你可以在github的問題部分報告它,那將是非常好的。 – mrdoob

+0

謝謝@mrdoob。我添加了一個問題:https://github.com/mrdoob/three.js/issues/2916 – Harold

回答

0

如果您正在編寫自己的着色器,則可以使用uniform變量作爲一般色調(不是頂點特定的),並將其傳遞到着色器中以考慮總體色彩。 vec4f_tvec4f()在C部分不是標準的,但是你的代碼可能已經有了等價物。

C:

vec4f_t hue = vec4f(....); // fill in as desired 
// load the shader so that GLuint shader_id is available. 
// "hue" is a uniform var in the vertexshader 
GLUint hue_id = glGetUniformLocation(shader_id, "hue"); 
// later, before rendering the object: 
glUniform4fv(hue_id, 1, &hue); 

的。頂點發球檯:

uniform vec4 hue; // add this and use it in the texture's color computation 
+0

當然。 (:但是,我希望能夠在不降低性能的情況下使用內置材質來做到這一點(即只支付您的方案中的統一套餐,這應該超快) – Harold

+0

我的印象是大多數支持頂點顏色(不是材質顏色)的着色器都傾向於期望一個數組被頂點交給頂點 - 索引數組可能是最接近的。vec4色調的想法看起來相當不尋常,但應該是非常容易添加到頂點着色器的頂點顏色計算中,但是如果您只計劃使用預定義的着色器,那麼仍然有可能徹底搜索網頁可能會打開一個。 –

+0

再次感謝您的回答。關於three.js WebGL庫,你的答案與直接使用OpenGL有關(可能對別人有幫助) – Harold

3

是的。每個對象使用material.clone()克隆您的材料,修改其emissivecolor,並將對象的材質設置爲此克隆。着色器和屬性通過引用複製,所以不要擔心每次都克隆整個材質;實際上唯一被價值複製的東西是制服(如emissivecolor)。所以你可以改變這些每個單獨的對象。

就我個人而言,我將原始資料存儲在對象的單獨自定義屬性中,以便以後可以輕鬆切換回來;取決於你的需求。

+0

你能否詳細說明「克隆你的材料」嗎?這與構造不同爲每個對象添加一個新的'THREE.MeshPhongMaterial'?如果是這樣,怎麼樣? – Harold

+0

@Harold'material.clone()'。它在基礎「材料」類的API文檔中。它存在於three.js中的大多數其他類型的對象。由於我不知道以前如何構建單獨的實物對象,因此我無法告訴您它是相同還是不同。我可以告訴你的是,大部分數據都是通過引用共享的。 –

+0

如果我有機會我會試驗這個;我們目前不使用'.clone()'。感謝你的想法。 – Harold

相關問題