Estoy usando C # y XNA. Mi algoritmo actual para la iluminación es un método recursivo. Sin embargo, es costoso , hasta el punto en que se calcula un fragmento de 8x128x8 cada 5 segundos.
- ¿Existen otros métodos de iluminación que harán sombras de oscuridad variable?
- ¿O es bueno el método recursivo, y tal vez lo estoy haciendo mal?
Parece que las cosas recursivas son fundamentalmente caras (forzadas a atravesar alrededor de 25k bloques por trozo). Estaba pensando en usar un método similar al trazado de rayos, pero no tengo idea de cómo funcionaría. Otra cosa que intenté fue almacenar las fuentes de luz en una Lista, y para cada bloque obtener la distancia a cada fuente de luz, y usarla para iluminarla al nivel correcto, pero luego la iluminación atravesaba las paredes.
Mi código de recursión actual está debajo. Esto se llama desde cualquier lugar en el trozo que no tenga un nivel de luz de cero, después de limpiar y volver a agregar la luz solar y la luz de las antorchas.
world.get___at
es una función que puede obtener bloques fuera de este fragmento (está dentro de la clase de fragmento). Location
es mi propia estructura que es como a Vector3
, pero usa números enteros en lugar de valores de coma flotante. light[,,]
es el mapa de luz para el fragmento.
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);
}