Ich benutze C # und XNA. Mein aktueller Algorithmus für die Beleuchtung ist eine rekursive Methode. Es ist jedoch teuer , bis zu dem Punkt, an dem alle 5 Sekunden ein 8x128x8-Block berechnet wird.
- Gibt es andere Beleuchtungsmethoden, die Schatten mit variabler Dunkelheit erzeugen?
- Oder ist die rekursive Methode gut, und vielleicht mache ich es einfach falsch?
Es scheint nur so, als ob rekursives Zeug grundsätzlich teuer ist (gezwungen, ungefähr 25.000 Blöcke pro Block zu durchlaufen). Ich habe überlegt, eine Methode zu verwenden, die der Raytracing-Methode ähnelt, aber ich habe keine Ahnung, wie dies funktionieren würde. Eine andere Sache, die ich versuchte, war, Lichtquellen in einer Liste zu speichern und für jeden Block den Abstand zu jeder Lichtquelle zu ermitteln und diesen zu verwenden, um sie auf das richtige Niveau zu bringen, aber dann würde die Beleuchtung durch Wände gehen.
Mein aktueller Rekursionscode ist unten. Dies wird von jeder Stelle im Chunk aufgerufen, die keine Lichtstärke von Null aufweist, nachdem das Sonnenlicht und das Fackellicht gelöscht und erneut hinzugefügt wurden.
world.get___at
ist eine Funktion, die Blöcke außerhalb dieses Chunks abrufen kann (dies ist innerhalb der Chunk-Klasse). Location
ist meine eigene Struktur, die a ähnelt Vector3
, aber Ganzzahlen anstelle von Gleitkommawerten verwendet. light[,,]
ist die Lightmap für den Chunk.
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);
}