Я использую C # и XNA. Мой текущий алгоритм освещения - рекурсивный метод. Тем не менее, это дорого , до такой степени, что один кусок 8x128x8 рассчитывается каждые 5 секунд.
- Существуют ли другие методы освещения, которые будут создавать тени переменной темноты?
- Или рекурсивный метод хорош, и, возможно, я просто делаю это неправильно?
Просто кажется, что рекурсивные вещи в корне дороги (вынуждены проходить около 25 тыс. Блоков на кусок). Я думал об использовании метода, подобного трассировке лучей, но я понятия не имею, как это будет работать. Еще я пытался хранить источники света в Списке, и для каждого блока получать расстояние до каждого источника света и использовать его для освещения до нужного уровня, но тогда освещение будет проходить через стены.
Мой текущий код рекурсии ниже. Это вызывается из любого места в чанке, где уровень освещения не равен нулю, после очистки и повторного добавления солнечного света и света факела.
world.get___at
это функция, которая может получать блоки вне этого чанка (это внутри класса чанка). Location
моя собственная структура, которая похожа на a Vector3
, но использует целые числа вместо значений с плавающей запятой. light[,,]
это карта света для куска.
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);
}