2013-01-03 12 views
17

Ho un numero elevato (~ 1000) di THREE.Mesh oggetti che sono stati costruiti dallo stesso THREE.Geometry e THREE.MeshPhongMaterial (che ha una mappa).Molte maglie con la stessa geometria e materiale, posso cambiare i loro colori?

Vorrei colorare questi oggetti singolarmente.

Naïvely, ho provato a modificare la proprietà mesh.material.color, ma la modifica di questa proprietà su uno qualsiasi degli oggetti cambia il colore di tutti gli oggetti contemporaneamente. Questo ha senso, dal momento che c'è un solo materiale che è condiviso tra tutti gli oggetti.

La mia prossima idea era quella di creare uno THREE.MeshPhongMaterial separato per ciascun oggetto. Quindi, ora ho un gran numero di oggetti THREE.Mesh che sono stati costruiti dallo stesso THREE.Geometry, ma hanno singoli THREE.MeshPhongMaterials (che condividono la stessa trama). Questo mi permette di cambiare i colori individualmente, ma la performance è peggiore. Il chrome profiloer mostra che l'app sta spendendo molto tempo a fare cose materiali come cambiare textures.

Il colore del materiale è solo un'uniforme nello shader. Quindi, aggiornare quell'uniforme dovrebbe essere piuttosto veloce.

domanda: C'è un modo per ignorare un colore del materiale dal livello di mesh?

Se ci fosse, credo che potrei condividere il materiale tra tutti i miei oggetti e riprendere le mie prestazioni, mentre cambio ancora i colori individualmente.

[Ho testato su v49 e V54, hanno prestazioni identiche e degradazione]

aggiornamento: Ho costruito un banco di prova, e la caduta di prestazioni a causa di questo è inferiore ho pensato che fosse, ma è ancora misurabile.

Qui ci sono due link:

Nel primo caso, ci sono solo due materiali, nel secondo caso ogni cubo ha il proprio materiale. Misuro il framerate del primo caso per essere 53fps su questa macchina, e il framerate del secondo è 46fps. Si tratta di un calo del 15%.

In entrambi i casi, il colore del materiale di ogni cubo viene modificato ogni fotogramma. Nel caso di molti materiali, vediamo effettivamente ogni cubo ottenere il proprio colore, nel caso di soli due materiali, li vediamo tutti con lo stesso colore (come previsto).

+2

Uhm, sembra un "bug". Se riesci a riprodurre il problema con r54 sarebbe bello se potessi segnalarlo nella sezione dei problemi su github. – mrdoob

+0

Grazie a @mrdoob. Ho aggiunto un problema: https://github.com/mrdoob/three.js/issues/2916 – Harold

risposta

0

Se si scrivono i propri shader, è possibile utilizzare una variabile uniform per una tinta generica (non specifica del vertice) e passarla allo shader per il factoring nel colore generale. vec4f_t e vec4f() non sono standard nella parte C, ma il codice probabilmente ha già equivalenti.

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); 

il.vertexshader:

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

Naturalmente. (: Tuttavia, mi piacerebbe essere in grado di farlo con i materiali incorporati senza il degrado delle prestazioni. (Vale a dire, paghi solo per il set uniforme come nel tuo schema, che dovrebbe essere super-veloce) – Harold

+0

La mia impressione è che la maggior parte degli shader che supportano il colore del vertice (non per i colori dei materiali) tenderebbe ad aspettarsi che una matrice venga passata per i vertici - un array indicizzato potrebbe essere il più vicino.L'idea di vec4 hue sembra piuttosto insolita come un singolo componente, ma dovrebbe essere abbastanza facile da aggiungere al calcolo dei vertici di un vertex shader: se si è pianificati solo per la valutazione con shader predefiniti, tuttavia, c'è ancora una possibilità che una ricerca approfondita sul Web ne possa trasformare 1. –

+0

Grazie ancora per la risposta. sulla libreria WebGL Three.js. La tua risposta riguarda l'utilizzo diretto di OpenGL (che potrebbe essere utile a qualcun altro) – Harold

3

Sì. Per oggetto, clona il tuo materiale utilizzando material.clone(), modifica il suo emissive e color e imposta il materiale dell'oggetto su questo clone. Gli shader e gli attributi vengono copiati per riferimento, quindi non preoccuparti di dover clonare l'intero materiale ogni volta; infatti le uniche cose copiate dal valore sono le uniformi (come emissive e color). Quindi puoi cambiare questi per ogni singolo oggetto.

Personalmente, memorizzo il materiale originale su una proprietà personalizzata separata dell'oggetto, così posso facilmente tornare ad esso in seguito; dipende da quali sono i tuoi bisogni

+0

Puoi approfondire "clonare il tuo materiale"? È diverso dal costrutto ng un nuovo 'THREE.MeshPhongMaterial' per ogni oggetto? Se é cosi, come? – Harold

+0

@Harold 'material.clone()'. È nei documenti API per la classe 'Material' di base. Ed esiste per la maggior parte degli altri tipi di oggetti in three.js. Dal momento che non ho idea di come sia andata in precedenza la costruzione di un oggetto materiale separato, non potrei dirti se è uguale o diverso. Tutto quello che posso dire è che la maggior parte dei dati è condivisa per riferimento. –

+0

Se avrò la possibilità sperimenterò questo; non stiamo usando '.clone()' al momento. Grazie del pensiero. – Harold

Problemi correlati