Sto lavorando per impostare un contorno attivo nel mio motore 3d, un effetto di evidenziazione per i personaggi 3d selezionati o uno scenario sullo schermo. Dopo aver lavorato con il buffer dello stencil e aver ottenuto risultati insoddisfacenti (problemi con forme concave, spessore del contorno dovuto alla distanza dalla fotocamera e incoerenze tra il desktop e il laptop), sono passato al rilevamento dei bordi e al campionamento del frame buffer e ho ottenuto un profilo abbastanza soddisfatto.
Tuttavia, non sono in grado di nascondere il contorno quando la mesh selezionata si trova dietro un'altra mesh. Questo ha senso dato il mio processo, dal momento che eseguo semplicemente il rendering del contorno dello shader 2D da un frame buffer dopo aver eseguito il rendering del resto della scena.
Di seguito sono riportate due schermate dei miei risultati. Il primo è un contorno "buono", il secondo è dove il contorno è visto su una mesh che blocca la sorgente del contorno.
Il processo di rendering funziona in questo modo: 1) Disegna solo l'alfa della mesh evidenziata, catturando una silhouette nera in un frame buffer (framebuffer1).
2) Passa la trama da framebuffer1 a un secondo shader che esegue il rilevamento dei bordi. Cattura il bordo nel framebuffer2.
3) Rendering dell'intera scena.
4) Rendering della trama da framebuffer2 nella parte superiore della scena.
Ho alcune idee su come realizzare e spero di ottenere un feedback sulla loro validità o su metodi più semplici o migliori.
Innanzitutto, ho pensato di rendere l'intera scena in un frame buffer e di archiviare la silhouette visibile della mesh evidenziata nel canale alfa (tutto bianco tranne il punto in cui è visibile la mesh evidenziata). Vorrei quindi eseguire il rilevamento dei bordi sul canale alfa, renderizzare il frame buffer della scena e quindi renderizzare il bordo in alto. Ne risulta qualcosa del genere:
Per fare ciò, ho pensato di impostare una definizione solo durante il passaggio di rendering dell'oggetto evidenziato che avrebbe disegnato tutto il nero in alfa per eventuali pixel visibili.
La mia seconda idea è quella di utilizzare l'attuale processo di rendering descritto sopra, ma anche di memorizzare le coordinate X, Y e Z nei canali R, G e B di framebuffer1 quando si esegue il rendering della silhouette della mesh selezionata. I rilevamenti dei bordi sarebbero stati eseguiti e memorizzati in framebuffer2, ma avrei trasmesso i valori RGB / XYZ dai bordi dell'alfa alla silhouette. Quindi, durante il rendering della scena, verificherei se le coordinate si trovano all'interno del bordo memorizzato in framebuffer2. In tal caso, verificherei quindi la profondità del frammento corrente per determinare se si trova davanti o dietro le coordinate estratte dai canali RGB (convertite nello spazio della fotocamera). Se il frammento si trova davanti alle coordinate di profondità, il frammento verrebbe visualizzato normalmente. Se il frammento è dietro, verrebbe visualizzato come il colore del contorno solido.
Sto usando LibGDX per questo progetto e vorrei supportare WebGL e OpenGL ES, quindi nessuna delle soluzioni che coinvolgono shader di geometria o nuove funzioni GLSL sono disponibili per me. Se qualcuno potesse commentare i miei approcci proposti o proporre qualcosa di meglio, lo apprezzerei davvero.