Come posso eseguire il rendering procedurale di barre della salute di forma irregolare?


35

Il problema della tradizionale barra della salute rettangolare o basata sul cuore è qualcosa di ben compreso e facilmente risolvibile. Ma qual è la soluzione accettata per più barre della salute "a forma di creatività", come il modello che ho fatto di seguito?

Salute vuota Salute completa, salute parziale

Il modo ovvio per farlo sarebbe quello di avere sprite "nel mezzo", quindi la terza immagine sarebbe il suo sprite, insieme a molte altre transizioni per diversi livelli di salute. Ma questo sembra davvero inelegante e il numero di in-betweens necessari per creare una transizione graduale tra stati di salute sarebbe grande.

L'unica altra idea che mi viene in mente è quella di sovrapporre lo sprite "full health" sopra lo sprite "empty health" e i set di coordinate pixel pre-forno per rappresentare ogni segno di spunta della salute e quindi renderli opachi o trasparenti come salute va su o giù.

Intendo che questa domanda sia indipendente dalla lingua e dalla piattaforma, ma mi sento libero di fornire un campione concreto in qualsiasi lingua / biblioteca / quadro se aiuta la risposta.


5
"N̶a̶n̶o̶m̶a̶c̶h̶i̶n̶e̶s̶ Shaders, son"
Mukesh Ingham,

Sento che quella transizione potrebbe essere definita matematicamente, da lì puoi fare in modo che il computer calcoli le coordinate dei pixel per mostrarle / nasconderle piuttosto che pre-prepararle
Richard Tingle,

In che modo la barra della salute a forma di cuore viene "facilmente risolta"?
MooseBoys,

1
@MooseBoys Stavo parlando della salute a base di cuore, non a forma di cuore. Pensa ai giochi Legend of Zelda. Scusa per non essere più chiaro.
msd7734,

@RichardTingle, buona idea :)
Jon,

Risposte:


48

C'è un modo molto semplice per ottenere questo risultato con gli shader, sono necessarie tre * trame: barra della salute vuota, struttura della barra della salute e maschera con gradiente di distribuzione della salute con un estremo (ad esempio il valore alfa più scuro non nero o più trasparente) su un'estremità e il altro dall'altra parte. È meglio mostrato sull'immagine, al momento non riesco a disegnare un gradiente curvo solo uno lineare - ma sono sicuro che i tuoi artisti non avranno alcun problema: inserisci qui la descrizione dell'immagine ora, nello shader campiona sia le trame che la soglia del valore della maschera, scartando tutti i pixel che non sono più luminoso della soglia di input (basato sull'input% shader di integrità).
si potrebbe usa la formula matematica per mascherare invece di una trama, ma se lo facessi, saresti ancora molto limitato alle forme che puoi (= semplici) creare con dette formule - e trovarne una non è banale.
* vedi commenti


9
In molti casi (incluso l'esempio del PO) l'uso di una trama separata per il colore è eccessivo. Nella maggior parte dei casi è possibile rimappare la sfumatura della maschera di gradazione di grigio ai colori specificati come uniformi nello shader, eliminando comunque qualsiasi valore di maschera al di sotto di una determinata soglia.
bcrist

1
In realtà non hai bisogno del più scuro, non del nero, puoi usare il canale alfa per schermare i pixel che non vuoi.
Jack Aidley,

1
@JackAidley sicuramente sarebbe possibile, ma volevo che la soluzione fosse il più flessibile possibile - nella maggior parte dei titoli AAA non hai hp solo "rosso" ma è strutturato.
Wondra,

1
@bcrist buon punto, ho considerato di suggerirlo come un'ottimizzazione. Ma non ho potuto disegnarlo correttamente, quindi ho deciso di renderlo il più semplice possibile e lasciare l'ottimizzazione per l'implementazione.
Wondra,

@wondra In molti casi, incluso l'esempio di esempio nell'OP, è possibile utilizzare una sfumatura procedurale o una ricerca del colore unidimensionale (con il livello della maschera come input), anziché una trama.
Casuale 832,

34

Implementato matematicamente, come pixel shader:

Sulla CPU, calcola HealthDirection e il suo 'punto prodotto con V2 inserisci qui la descrizione dell'immagine

Sulla GPU, calcola una direzione normalizzata lontano dal punto centrale per ciascun pixel. Confronta ogni prodotto punto con HealthDirections 'per scegliere se sfumare "sfondo" o a colori. inserisci qui la descrizione dell'immagine

Se hai "invertito" questo algoritmo e hai lavorato dall'altra direzione, potresti "sbloccare" la direzione di ciascun pixel in una percentuale e confrontarla con HealthPercent. Con la percentuale di ciascun pixel calcolata, eseguire la dissolvenza da rosso a verde sulla GPU diventa banale.

Disegna prima la barra applicando l'algoritmo a un quad; colori di output tra rangeMin e rangeMax (potrebbe essere cotto) e clip () o output trasparenti ovunque. Quindi, disegna lo sprite (modificato) su di esso, usando l'alfa. Ho tracciato la tua barra in CAD, l'ho riempita, quindi "incantato magicamente" la forma a tinta unita in Paint per eliminarla. Il mio sembra una merda a causa della miscelazione automatica di AutoCAD e Paint; supponendo che abbini i bordi interni a trasparenti, i tuoi sembreranno perfetti .

Il bordo bianco è i limiti del quad. Esso e le X rosse sono solo di riferimento:

inserisci qui la descrizione dell'immagine

Non è necessario eseguire il rendering di "sprite con foro" contemporaneamente alla barra della salute. Dovrebbero essere istanziati e disegnati tutti in una volta, dopo che tutte le barre della salute sono state completate. Poiché l'algoritmo è autonomo nello shader, è anche possibile aggiungere istanze ad esso e quindi, anche, disegnare tutte le barre della salute con una chiamata di richiamo istanziata. Disegnare tutte le barre della salute sullo schermo dovrebbe richiedere 2 chiamate DrawInstanced (...) ed essere "follemente veloce".


1
Se hai intenzione di mascherarti in modo circolare come questo, puoi implementarlo in modo più efficiente semplicemente alterando i triangoli tracciati per una dissolvenza circolare.
Jack Aidley,

@JackAidley, per favore sii più specifico, perché non considero questo mascheramento; la barra di avanzamento viene visualizzata completamente, in posizione, solo su due triangoli, senza campionamento, dopo il primo passaggio. Lo sprite sembra avere un buco in esso e "incanta" il tutto alla fine. (È una sorta di maschera, ma non come parte integrante dell'algoritmo?) Grazie
Jon,

Quello che stai facendo equivale a disegnare una versione mascherata colorata della barra colorata su uno sprite di sfondo che ha già il colore grigio in posizione. Perché il tuo metodo richiede uno shader personalizzato e scrive su ogni pixel che finisci con un metodo più lento rispetto al disegno solo della parte desiderata della forma.
Jack Aidley,

@JackAidley, ma non c'è uno sprite di fondo? L'arcobaleno viene disegnato usando solo quattro posizioni mondiali float3; nessun UV, nessuno "sprite di sfondo". Inoltre, sei preoccupato che il pixel shader si impantanerà lavorando su alcuni piccoli quad? Inoltre, RangeMin e RangeMax ritagliano () la maggior parte di quei frammenti, all'istante.
Jon,

Avrai bisogno di uno sprite di sfondo per ottenere i bordi come mostrato nell'immagine originale; se si omettono questi, sì, i metodi sono diversi.
Jack Aidley,
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.