Shadow casting in tempo reale in un gioco isometrico 2D


15

Sto scrivendo un piccolo motore isometrico 2D in C ++ e sto cercando di implementare il casting ombra in tempo reale. Ho seguito un approccio semplice descritto in questa pagina ed ecco il risultato (la luce si trova nella stessa posizione del cubo giallo):

inserisci qui la descrizione dell'immagine

Il risultato è molto bello ma mancano ombre sui muri e sulla cima dei cubi. Ecco un esempio di come dovrebbe apparire (ho disegnato le ombre previste in verde):

inserisci qui la descrizione dell'immagine

Tutti i cubi disegnati sono semplicemente costituiti da 3 quadratini 2D situati in una posizione XY e con una profondità Z (z = x + y). Uso OpenGL con una matrice ortografica (glOrtho). Le ombre vengono disegnate usando il buffer dello stencil.

Sto cercando risorse o soluzioni che mi aiutino a completare questa implementazione di shadow casting.

Molte grazie!


5
Il tuo link a "questa pagina" punta a un'immagine e non a una pagina. Inoltre, sto solo indovinando qui, ma potrebbe essere più facile risolvere quel problema in 3D e proiettare la videocamera in modo iosmetrico.
Tetrad,

Oups, hai ragione, ho corretto il link. Sarebbe sicuramente più facile con una proiezione 3D ma anche il 2D ha i suoi vantaggi e sono sicuro che ci sono soluzioni per implementarlo in 2D.
XPac27,

Risposte:


6

Per tetto e pareti, puoi provare a determinare le intersezioni tra i segmenti di muro e le regioni di ombre generate. Hai bisogno del rendering a due passaggi delle tue ombre. Il primo farà quello che stai facendo oggi (nella memoria). Il secondo passaggio calcolerà le intersezioni tra tetto e parete. L'ultima fase è il rendering reale. DeadMG è sbagliato, puoi farlo.

Nota: per il tetto è necessario intersecare l'area d'ombra e l'area del tetto.


Grazie per il buon consiglio! Se può essere in grado di ottimizzare questo secondo passaggio controllando quali pareti devono essere calcolate usando il prodotto punto del loro segmento rispetto a quelli delle ombre. Lo proverò e rispedirò se funziona.
XPac27,

È passato un po 'di tempo, ma finalmente ho funzionato grazie ai tuoi suggerimenti! Avevo bisogno solo di 2 metodi geometrici (uno per sapere se un punto si trova all'interno di un poligono e uno per ottenere l'intersezione di due segmenti). Devo ancora gestire i tetti, ma sembra facile saperlo. Puoi guardare il risultato su questo video e guardare il codice sorgente qui (ho appena lavorato 1 giorno su di esso, quindi potrebbe essere possibile ottimizzarlo di più).
XPac27,

@ XPac27 è fantastico. Grazie per la condivisione.
ashes999,

0

Fondamentalmente, ciò che stai cercando non può essere fatto. Vuoi prendere un mucchio di oggetti 2D e farli proiettare ombre come se fossero oggetti 3D. Se vuoi avere ombre 3D complete, devi avere oggetti 3D.


1
Ma questo non è il casting di ombre 3D come nella domanda. Qualsiasi muro blocca completamente la linea di mira in quella direzione, non puoi avere oggetti di altezza variabile.
yuriks,

0

La soluzione descritta non è completamente 3d in quanto non necessita di una soluzione 3d completa. Sembrerà ma non lo è. La creazione di ombreggiatura deve essere considerata come intersezione tra i volumi. Ciò di cui ha bisogno è meno complicato. Ricorda (se hai kown) dooms e dooms come render engine. Tutta l'elaborazione è stata eseguita su due dimensioni.


0

Dato che vuoi che questo gioco sia piccolo, che ne dici di dire che l'attuale implementazione shadow è abbastanza buona?

Ammetto che non l'ho visto in azione, cioè non ho visto quanto saranno fastidiose o non disturbanti le imperfezioni dell'ombra quando questo gioco sarà in diretta con oggetti dinamici e sorgenti luminose dinamiche ma a giudicare dalle tue immagini, io ' Sono molto tentato di dire "è abbastanza buono, ora concentrati sul completamento del gioco". Se l'implementazione attuale sembra essere piccola ed esegue velocemente e risolvendo ciò che percepisci come problemi trasformerà il codice in grande e lento, penso che tu sia meglio non preoccuparti di quelle ombre.

Lo so, lo so, suggerendo "non provare a risolvere il problema" poiché una soluzione a un problema potrebbe essere una cattiva pratica. Tuttavia, voglio onestamente dire che è davvero buono come lo è se vuoi un footprint ridotto per il tuo codice.

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.