Двухмерное окружающее освещение в OpenGL

Я делаю 2D-игру с боковой прокруткой, и в настоящее время я реализую свет. Огни — это просто светлая градиентная текстура, отрисованная поверх ландшафта, умноженная, чтобы сделать область ярче. Однако я не знаю, как и не понимаю, как сделать окружающее освещение. Следующая картинка суммирует то, что у меня есть, а нижняя часть — это то, что я хочу.

введите здесь описание изображения

Я открыт для ответов о шейдерах, потому что знаю, как их использовать.


person sgtHale    schedule 12.08.2013    source источник
comment
Окружающее освещение простое, это основной цвет подсветки при отсутствии каких-либо источников света. Он однороден для всего вашего материала, и, поскольку он не имеет направления, вы можете комбинировать его с накопленным рассеянным членом в вашей модели освещения. Если вы делаете многопроходное освещение, вы должны сначала сделать проход, в котором ландшафт модулируется вашим постоянным фоновым элементом, а затем выполнять аддитивное смешивание для каждого дополнительного рассеянного/зеркального вклада света.   -  person Andon M. Coleman    schedule 13.08.2013
comment
Итак, когда я визуализирую треугольники необработанных текстур местности, мне нужно пропустить их через шейдер окружающего освещения?   -  person sgtHale    schedule 13.08.2013
comment
Вроде, как бы, что-то вроде. По сути, вам нужно собрать все параметры освещения для каждого источника света (плюс глобальный параметр окружающей среды), а затем модулировать базовый цвет текстуры с помощью этого значения в конце. Таким образом, вы действительно должны выполнять аддитивное смешивание в следующем порядке: Ambient, Light0, Light1, Light2, ..., Light N, за которым следует последний проход мультипликативного смешивания с использованием основного цвета текстуры. Это: (Ambient + Diffuse‹Для каждого источника света›) * Базовый цвет   -  person Andon M. Coleman    schedule 13.08.2013
comment
Просто для уточнения терминологии. Окружающий свет является грубым приближением непрямого освещения. Поскольку непрямой свет может только увеличить яркость, вам не нужно, чтобы это достигало нижнего изображения. Чтобы затемнить область изображения, вы можете просто уменьшить соответствующие коэффициенты на карте освещения.   -  person a.lasram    schedule 13.08.2013
comment
Отлично, это было очень полезно.   -  person sgtHale    schedule 13.08.2013
comment
Итак, забегая в последний раз, могу ли я создать один фреймбуфер, визуализировать на нем окружение, аддитивно визуализировать на нем источники света, а затем рисовать треугольники ландшафта, умножая текстуру ландшафта с помощью FBO?   -  person sgtHale    schedule 13.08.2013


Ответы (1)


В итоге я создал текстуру FBO размером с экран, очистив ее цветом окружения и нарисовав все близлежащие источники света. Затем я пропустил его через созданный мной шейдер, который использует 2 текстуры для униформы. Текстура для рисования и сам световой FBO. Шейдер умножает текстуры, отрисовываемые с помощью FBO, и получилось неплохо.

атмосфера.фрагмент

uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 texCoord;

void main( void ) {
    vec4 color1 = vec4(texture2D(texture1, gl_TexCoord[0].st));
    vec4 color2 = vec4(texture2D(texture2, texCoord));
    gl_FragColor = color1*vec4(color2.r,color2.g,color2.b,1.0);
}

атмосфера.vs

varying vec2 texCoord;
uniform vec2 screen;
uniform vec2 camera;

void main(){
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;
    vec2 temp = vec2(gl_Vertex.x,gl_Vertex.y)-camera;
    texCoord = temp/screen;
}
person sgtHale    schedule 13.08.2013
comment
Вы должны научиться использовать swizzling в GLSL. Вместо vec4 (color2.r, color2.g, color2.b, 1.0) вы можете сделать это: vec4 (color2.rgb, 1.0). Точно так же в вашем вершинном шейдере вы можете использовать gl_Vertex.xy вместо vec2 (gl_Vertex.x, gl_Vertex.y). Кроме того, если текстура 2 представляет собой трехканальный формат текстуры, четвертому компоненту автоматически присваивается значение 1.0 GLSL при его выборке. - person Andon M. Coleman; 14.08.2013
comment
Другое замечание: если вы собираетесь делать освещение таким образом, убедитесь, что вы используете проекцию orthographic, когда растягиваете текстуру FBO по экрану. Вам нужно, чтобы центры пикселей совпадали с центрами текселей, иначе вы столкнетесь с проблемами фильтрации текстур, размытыми (линейными) или сглаживающими (ближайшими). Коррекция перспективы часто приводит к неправильному выравниванию координат текстуры. Я ответил на аналогичный вопрос здесь: stackoverflow.com/questions /18152963/ недавно. - person Andon M. Coleman; 14.08.2013