Estou usando C # e XNA. Meu algoritmo atual para iluminação é um método recursivo. No entanto, é caro , a ponto de um pedaço de 8x128x8 ser calculado a cada 5 segundos.
- Existem outros métodos de iluminação que produzem sombras de escuridão variável?
- Ou o método recursivo é bom e talvez eu esteja fazendo errado?
Parece que o material recursivo é fundamentalmente caro (forçado a percorrer cerca de 25 mil blocos por bloco). Eu estava pensando em usar um método semelhante ao traçado de raios, mas não tenho idéia de como isso funcionaria. Outra coisa que tentei foi armazenar fontes de luz em uma lista e, para cada bloco, obter a distância de cada fonte de luz e usá-la para iluminá-la no nível correto, mas a iluminação atravessaria as paredes.
Meu código de recursão atual está abaixo. Isso é chamado de qualquer lugar no pedaço que não tenha um nível de luz zero, depois de limpar e adicionar novamente a luz solar e a lanterna.
world.get___at
é uma função que pode obter blocos fora desse bloco (isso é dentro da classe de bloco). Location
é minha própria estrutura que é como a Vector3
, mas usa números inteiros em vez de valores de ponto flutuante. light[,,]
é o mapa de luz do pedaço.
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);
}