Отличная статья тут:
http://www.redblobgames.com/articles/visibility/
Есть источник света, и есть отрезки - весь уровень сделан из отрезков. Далее бросить тень от одного отрезка - очень легко, как сделаешь это, дальше нужно будет оптимизировать: постройка одного triangle strip'а, не проверять отрезки которые уже в тени, ограничивание дальности тени по квадрату (чтобы не тянуть тень за радиус дальности света, иначе будет высокий fillrate).
Можно также делать частичное обновление в такой системе только для двигающихся объектов, такой подход дает возможность просчитать тени для статики один раз, заместо каждого раза. Производительность весьма высокая, даже в сложных сценах.
Можно также реализовать мягкие тени таким подходом.