2012-06-07 10 views
12

Ho cercato il problema che ho e non riesco a capirlo abbastanza bene da risolverlo, quindi ho pensato che avrei potuto buttarlo lì e il gruppo intelligente potrebbe avere qualche idea . : PGLKit's GLKBaseEffect e shader personalizzati

Fondamentalmente ho lavorato su un progetto iPhone per un po ', dove ho il lusso di usare tutti i più recenti framework e target 5.1. Quindi ho usato GLKit e GLKBaseEffect che funzionano bene per me. Il motivo per cui ho iniziato con GLKBaseEffect piuttosto che scrivere i miei shader è che non lo so bene. Tuttavia i requisiti sono diventati più precisi e l'effetto base non sembra più interromperlo.

Dato che sto già facendo tutte le mie trasformazioni usando l'effetto di base, preferirei mantenere il mio effetto di base intatto ma aggiungere ombreggiatori di tipo glsl in alto se questo ha senso.

Il mio vecchio approccio ha un aspetto simile a questo (questo è in un ciclo che esegue il rendering di tutti gli oggetti, in cui un oggetto contiene cose come trasformazioni, una mesh e alcune altre cose meno importanti per questo problema, come trame, materiali e così via)

ObjectBase *obj = [ResourceManager.shared getObjectNamed:name inScene:sceneName]; 
GLKMatrix4 modelview = effect.transform.modelviewMatrix; 
effect.transform.modelviewMatrix = GLKMatrix4Multiply(effect.transform.modelviewMatrix, obj.transform); 

[effect prepareToDraw]; 
[obj render]; 

effect.transform.modelviewMatrix = modelView; 

Qui recuperare un oggetto per rendere e trasformare (cioè traslare, ruotare e scala) l'oggetto allora rendiamo esso, dove la rendendosi recupera la maglia per l'oggetto, legano i buffer e rendere.

Fin qui tutto bene.

Quello che vorrei fare è che durante la chiamata [obj render]; vorrei che l'oggetto faccia anche qualcosa come glUseProgram(someProgram); aggiungendo altro codice shader specializzato.

Immagino che si possa sostenere che sto cercando di usare l'effetto di base per i vertex shader e voglio usare shader "normali" per i miei shader di frammenti. Almeno questo è quello che penso di voler fare.

Ho provato alcune cose.

Ho provato a creare solo gli shader di frammenti e glUseProgram su di esso, tuttavia ha detto che ho bisogno di un vertice e di uno shader di frammenti durante l'impostazione e la compilazione. Ho anche provato a creare uno shader vertex vuoto, che non è risultato molto buono, non so cosa succederà con questo, ma suppongo che prevale sull'effetto base.

Sono propenso a, alla fine, accettare che è probabilmente meglio gettare gli effetti di base e scrivere solo i miei stessi shader fino in fondo. Mi sembra che sia un sacco di lavoro fuori dalla finestra, quindi volevo vedere quanto posso risparmiare.

Capisco che la mia comprensione degli shader sia la parte che mi dà più problemi, quindi per favore sii paziente di questo fatto.

risposta

11

Proprio come hai scoperto, non puoi usare uno shader di frammenti e lasciare il vertex shader. Questo perché entrambi hanno compiti diversi. Gli shader vertici trattano gli aspetti per-vertice: calcola i dati dei vertici, texture (uv's) ecc. E infine traccia le facce (triangoli). Gli ombreggiatori di frammenti si occupano di ciò che verrà disegnato ad ogni pixel sullo schermo (o nel viewport). Quando fornisci solo uno shader di frammenti, sei non indicando quali sono i tuoi dati di vertice, piuttosto stai dicendo a OpenGL di fare qualcosa sui pixel. E questi pixel non contengono nulla/senza senso (non sono sicuro di quale) dal momento che il vertex shader non ha fatto nulla.

Quando si utilizza GLKEffect, una chiamata al metodo [yourEffect prepareToDraw] si prende cura dei shaders ecc

Se hai appena desidera utilizzare un paio magazzino dello shader, perché non utilizzare quello fornito nel modello di gioco XCode OpenGL? Quando lo esegui, ha due cubi, uno renderizzato usando GLKit e altri in modo normale. Anche se penso che non sarà sufficiente per la maggior parte degli effetti. Nel caso in cui desideri saperne di più sugli shader, puoi dare un'occhiata allo NeHe introduzione GLSL article. Riguarda GLSL e come puoi scrivere e usare shader nel tuo codice. Si consiglia di dare un'occhiata a Diney Bomfim's articoli All About Shaders e questo page.

L'utilizzo di GLKit è utile nella maggior parte dei casi, poiché consente di evitare di scrivere un sacco di codice inutile e ripetitivo. Ad esempio, non è necessario passare attraverso così tanti formati di immagine con codifiche e bit di colore diversi per pixel (per formato) e tutto ciò che si può semplicemente usare GLKTextureLoader.

+0

Mi sembra di aver completamente dimenticato di dire in realtà grazie ai link che hai fornito ho davvero ampliato la mia comprensione. Sono contento di averlo chiesto anche se, mentre chiedevo, sentivo che non avevo idea di cosa volessi veramente chiedere ... così buon lavoro a comprenderlo;) Grazie. – qrikko

+0

Grazie mille. Ero frustrato dal fatto che i miei ombreggiatori stessero compilando e collegando, ma non emettendo nulla. Rimozione della chiamata il prepareToDraw ha fatto il trucco. La vita è bella! – VaporwareWolf

18

Volevo solo dare le mie conclusioni per chiunque fosse interessato a loro.

Quello che ho fatto è stato effettivamente gettato via GLBaseEffect e ho implementato il mio codice shader.

Il mio più grande problema era che non capivo davvero che si tratta di tutto o niente per così dire.

Per favore potrei sbagliarmi, quindi qualsiasi correzione su dove sbaglio sarà molto apprezzata, davvero non voglio ingannare nessuno a leggerlo.

Quello che ho scoperto durante i miei sforzi è un paio di punti chiave:

  • GLKBaseEffect, ha lo scopo di simulare la funzione fissa gasdotto come si è visto nelle versioni precedenti di OpenGLES. Quindi si tratta del codice comune dello shader, quindi non ci si deve preoccupare molto di questo. Avrai funzionalità di base ma non è davvero molto estensibile.
  • È ancora possibile utilizzare le funzioni ordinate di GLKit come il caricatore di texture, la libreria matematica e così via se si scrive il proprio codice shader. Quindi, se si desidera qualcosa di più complicato o personalizzabile (bump mapping, toon shading e così via) è assolutamente necessario riscrivere il codice della piastra della caldaia necessario per il rendering corretto. Quello che ho fatto all'inizio è stato che ho usato GLKBaseEffect per orientarmi nella scena dato che è abbastanza comodo e facile da usare. Tuttavia, quando volevo fare di più (mappatura normale dello spazio tangente) mi sono bloccato perché non potevo aggiungere al programma shader gestito da GLKBaseEffect.
  • Gli shader non sono così spaventosi come ho sempre pensato! Non avevo proprio idea di cosa significasse realmente, e sono sorpreso di aver letto così tanto su di loro e ancora non avevo capito che fondamentalmente gli shader sono programmi che SOSTITUISCONO la pipeline della funzionalità fissa. Semplice come quella.

Quello è abbastanza rant, credo, volevo solo seguire e aggiungere che pezzi e pezzi che ho raccolto fino ad ora.

+0

ciao qrikko potrei mandarti una email su un potenziale progetto?grazie per la risposta dettagliata! – Crashalot

+0

Assolutamente, e nessun problema cerco sempre di essere estenuante in SO dato che è una risorsa così importante per così tante persone. :) – qrikko

+0

grazie, qual è la tua email? – Crashalot