Существует огромное количество способов сделать это. Это потребует использования шейдера, и я предполагаю, что вы уже используете освещение на пиксель. Ниже приведены некоторые предложения, однако для поиска подходящей техники может потребоваться гораздо больше исследований.
Быстро и грязно
Вы можете указать ограничивающие рамки, которые определяют внутренние области. Если источник света находится за пределами ящиков, но геометрия (которая не находится в тени) находится внутри ящика, то на свет должно было воздействовать прохождение через окно (это также верно, если геометрия находится за пределами ящика и источника света это внутри). Единственная проблема здесь заключается в том, как передать информацию о шейдере в шейдер и как указать эффект на свет.
Другой вариант - указать окна как объекты, лежащие на плоскостях. Сначала проверьте, находятся ли геометрия и источник света на противоположных сторонах плоскости, а затем пересекает ли путь между ними плоскость в точке в пределах границ окна. Это было бы точнее, чем в первом методе, и было бы проще иметь окна в одинаковые интерьеры с разными цветами стекла.
Продолжайте получать более подробную информацию о геометрическом представлении окон, и вы получите более точные результаты, но вычисления также станут более тяжелыми.
Эти методы будут работать достаточно хорошо для шутера в коридоре, но не так хорошо для динамичного или открытого мира, так как, вероятно, потребуется много настроек, чтобы он выглядел правильно без слишком большого количества артефактов. Кроме того, эти методы могут быстро стать немного интенсивнее, поэтому рекомендуется перейти к отложенному конвейеру затенения.
Карты теней
Другой вариант - сделать что-то похожее на отображение теней.
В картографировании теней вы генерируете какое-то растровое изображение мира, на который воздействует свет. Каждый пиксель, хотя и является цветом, на самом деле является расстоянием до ближайшего фрагмента непрозрачной геометрии (вы используете четыре байта для 1 float вместо 4 цветов). Если вы рассчитываете расстояние от источника света до фрагмента геометрии, и оно больше соответствующего значения в карте теней, тогда ваш фрагмент геометрии находится в тени (обычно вы используете луч между геометрией и источником света для индексации карты).
Если вы примените эту идею к своей проблеме, то вам нужно сохранить карту расстояния от источника света ближайшего куска прозрачной геометрии, а затем также сделать вторую карту цвета света после прохождения через эту геометрию ( просто цвет геометрии, если свет белый).
Если ваш кусок геометрии находится дальше, чем расстояние на этой карте, тогда используйте цвет карты, если нет, то используйте оригинальный светлый цвет.
Функция для расчета цвета для каждого пикселя на карте должна быть примерно такой; lightColor - перевернутыйWindowColor. Таким образом, для чистого белого света и чистого красного окна, которое не поглощает красный спектр, мы получаем; (255,255,255) - (0,255,255) = (255,0,0). Таким образом, цвет света на другой стороне чисто красный. Для более сложного прозрачного объекта, такого как витраж, вам может потребоваться поиск текстуры, чтобы получить цвет материала.
Если вы ищете что-то похожее, посмотрите Reflective Shadow Maps .
Этот метод предлагает большую точность и, возможно, будет лучшим, если вы хотите использовать сложные прозрачные геометрии, такие как витражи.
Попытка общего решения
В последнее время стало популярным кодировать информацию об освещении в виде вокселей (они предназначены не только для геометрии). В новейшем движке Crytek этот вид стратегии используется для улучшенного освещения ( объем распространения света ).
Вот общая идея:
- Создайте карту из равномерно распределенных кубов, которая охватывает вашу сцену (рассмотрите возможность использования кривых z-порядка ).
- Найдите способ хранения информации о падающем освещении для каждого вокселя (здесь полезны сферические гармонические представления).
- Найдите воксель, содержащий свет, и представьте этот свет в вокселе.
- Распространяйте свет наружу через смежные воксели (вроде как вода из майнкрафта)
- Рассчитайте, как геометрия в каждом вокселе будет влиять на проходящий через него свет (поглощать, отражать, пропускать)
- повторяйте, пока свет не погаснет
Существует много способов построения этой информации о вокселях, но приведенный выше список дает общее представление. Например; Вы можете начать с создания теневых карт / объемов и затем проецировать эту информацию на карту вокселей, чтобы вы могли быстро создать карту прямого освещения. Затем вы начинаете распространение от вокселей по краю зоны поражения. Имейте в виду, что в этом случае вы захотите игнорировать, является ли геометрия прозрачной или нет при генерации карты / объема теней.
На последнем этапе отложенного рендеринга при расчете освещенности геометрической точки вы просто используете геометрическую позицию, чтобы индексировать карту вокселей, чтобы узнать, как выглядит падающее освещение в этой точке пространства. Затем вы можете построить экранную карту со стороны процессора, или, возможно, сделать это с помощью cuda.