Sto usando C # e XNA. Il mio attuale algoritmo per l'illuminazione è un metodo ricorsivo. Tuttavia, è costoso , al punto in cui un pezzo 8x128x8 calcolato ogni 5 secondi.
- Esistono altri metodi di illuminazione che renderanno ombre a oscurità variabile?
- O il metodo ricorsivo è buono e forse sto solo sbagliando?
Sembra che le cose ricorsive siano fondamentalmente costose (costrette a passare circa 25k blocchi per blocco). Stavo pensando di utilizzare un metodo simile al ray tracing, ma non ho idea di come funzionerebbe. Un'altra cosa che ho provato è stata la memorizzazione di sorgenti luminose in un elenco e per ogni blocco ottenere la distanza da ciascuna sorgente luminosa e usarla per illuminarla al livello corretto, ma poi l'illuminazione passava attraverso i muri.
Il mio attuale codice di ricorsione è sotto. Questo viene chiamato da qualsiasi punto del blocco che non ha un livello di luce pari a zero, dopo aver eliminato e aggiunto nuovamente luce solare e fiaccolata.
world.get___at
è una funzione che può ottenere blocchi al di fuori di questo blocco (questo è all'interno della classe di blocco). Location
è la mia struttura che è simile a Vector3
, ma utilizza numeri interi anziché valori in virgola mobile. light[,,]
è la mappa luminosa per il pezzo.
private void recursiveLight(int x, int y, int z, byte lightLevel)
{
Location loc = new Location(x + chunkx * 8, y, z + chunky * 8);
if (world.getBlockAt(loc).BlockData.isSolid)
return;
lightLevel--;
if (world.getLightAt(loc) >= lightLevel || lightLevel <= 0)
return;
if (y < 0 || y > 127 || x < -8 || x > 16 || z < -8 || z > 16)
return;
if (x >= 0 && x < 8 && z >= 0 && z < 8)
light[x, y, z] = lightLevel;
recursiveLight(x + 1, y, z, lightLevel);
recursiveLight(x - 1, y, z, lightLevel);
recursiveLight(x, y + 1, z, lightLevel);
recursiveLight(x, y - 1, z, lightLevel);
recursiveLight(x, y, z + 1, lightLevel);
recursiveLight(x, y, z - 1, lightLevel);
}