Come nascondere un contorno mesh post-elaborato quando / dove la mesh è nascosta


10

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.

inserisci qui la descrizione dell'immagine

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:

risultato

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.


Dai un'occhiata al tuo repository. Hai mai trovato una soluzione accettabile?
iKlsR,

Risposte:


0

Vorrei rendere l'intera scena in un buffer di stencil con l'oggetto delineato desiderato per impostare un bit e per qualsiasi altra cosa scartare / rimuovere il bit.

Quindi sbarazzarsi del rilevamento dei bordi, non è necessario, invece è possibile ingrandire leggermente il buffer. Quindi ogni oggetto cresce leggermente.

Da lì il buffer dello stencil può avere il contorno di cui hai bisogno. Si tratta di assicurarsi che gli altri oggetti che si stanno visualizzando stiano disattivando i bit nel buffer dello stencil.


2
Grazie per la risposta. Questo metodo non incorrerebbe in problemi simili con lo spessore del contorno e le forme concave se il ridimensionamento viene eseguito in 3d? O problemi di spostamento se è stato fatto in 2d e l'oggetto delineato non si trova nel punto morto dello schermo?
nils

0

1) in un oggetto frame buffer, è possibile eseguire uno shader laplaciano nella GPU per ottenere il contorno.

2) devi usare il buffer di profondità finale quando disegni il tuo oggetto nell'FBO, in questo modo disegnerai solo la parte visibile del tuo oggetto nell'FBO e il laplaciano disegnerà solo la parte visibile.


Ciao, grazie per la risposta. Lo sto già facendo per ottenere il profilo che ho. Non penso che ti meriti un voto negativo per questa risposta, quindi votazione.
nil

0

Spero di poterlo chiarire, ma fondamentalmente è necessario creare uno stencil di entrambi gli oggetti come se fossero entrambi selezionati, quindi mantenere solo le aree nel riquadro di delimitazione dell'elemento che si desidera effettivamente evidenziare.

Quindi fondamentalmente fai uno stencil buffer di entrambi gli oggetti selezionati (o tutti gli oggetti che occludono l'oggetto, davvero ... ma non mi preoccuperei di quei casi a meno che non si verifichino molto - se è che le persone occluse non si aspetteranno così tanto aiuto), e poi con uno stencil del rettangolo di selezione per il tuo oggetto.

Questo dovrebbe ottenere l'effetto che stai cercando.

In alternativa puoi semplicemente lasciare il risultato "cattivo" e non credo che la maggior parte delle persone si preoccuperà troppo, anche se questo dipende dai tuoi dati / giochi e soprattutto dalle dimensioni degli oggetti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.