Я використовую C # і XNA. Мій поточний алгоритм освітлення - це рекурсивний метод. Однак це дорого , до того моменту, коли один шматок 8x128x8 розраховувався кожні 5 секунд.
- Чи існують інші методи освітлення, які дозволять зробити тіні зі змінною темрявою?
- Або рекурсивний метод хороший, і, можливо, я просто роблю це неправильно?
Це здається, що рекурсивний матеріал є принципово дорогим (змушений пройти близько 25 тис. Блоків за шматок). Я думав про використання методу, подібного до трасування променів, але не маю уявлення, як це буде працювати. Інша річ, яку я спробував, - це зберігання джерел світла в списку, і для кожного блоку отримувати відстань до кожного джерела світла, і використовувати це для його освітлення до потрібного рівня, але тоді освітлення проходитиме через стіни.
Мій поточний код рекурсії нижче. Це називається з будь-якого місця в шматку, що не має рівня нульового рівня, після очищення та повторного додавання сонячного світла та факела.
world.get___at
це функція, яка може отримувати блоки поза цим фрагментом (це всередині класу фрагмента). Location
це моя власна структура, яка є як 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);
}