Как изобразить состояние источников света в OpenGL
Поэтому я хочу, чтобы в моей сцене было несколько источников света. Основная идея состоит в том, чтобы просто иметь массив (однородной) структуры, которая имеет все свойства света, которые вас интересуют, такие как положение, цвет, направление, обрезание и / или вы хотите. Моя проблема в том, как представить, какие огни включены / выключены? Я перечислю все способы, которые я могу придумать. Pl
- Иметь единое целое для каждой структуры света, чтобы указать, если он включен / выключен.
- Имейте число, совпадающее с кратным 2, 3 или 4, так что я могу использовать столько векторов bool, чтобы указать их статус. Например, 16 лампочек = 4х4 бвек4.
- Вместо того, чтобы использовать много флагов и веток, всегда проходите через каждый источник света, но с выключенными для цвета (0,0,0,0)
Я склоняюсь к последним вариантам, поскольку у них не будет ветвления... но я уже читал, что современная видеокарта теперь более подходит для ветвления.
1 ответ
Ни одна из ваших идей не является действительно хорошей, потому что все они требуют, чтобы шейдер оценил, какие источники света активны, а какие нет. Вы также должны различать информацию сцены (какие источники света присутствуют в сцене) и данные, необходимые для рендеринга (какие источники света включены и освещают сцену). Информация о сцене не должна храниться в шейдере, поскольку она не нужна и будет только замедлять работу шейдера.
Лучший способ обработки нескольких источников света в сцене и рендеринга только с активными источниками может быть следующим:
В каждом кадре:
Оцените на стороне процессора, какие индикаторы включены. Передайте только источники света, которые включены в форму шейдера, вместе с общим количеством активных источников света. В псевдокоде:
Shader:
uniform lightsources active_lightsources[MAX_LIGHTS]; uniform int light_count;
ЦПУ:
i = 0 foreach (light in lightsources) { if (light.state == ON) { set_uniform("active_lightsources[i]", light); i++ } } set_uniform("light_count", i);
При освещении фрагмента сделайте следующее в шейдере
Shader:
for (int i = 0; i < light_count; i++) { //Calculate illumination from active_lightsources[i] }
Основным преимуществом этого подхода является то, что вы храните меньше света внутри шейдера, и что петля внутри шейдера зацикливается только на источниках света, которые имеют отношение к текущему кадру. Оценка того, какие источники света актуальны, выполняется один раз за кадр в CPU, а не один раз за вершину / фрагмент в шейдере.