У меня снова вопрос. Сделал deferred shading по урокам Борескова с сайта
http://steps3d.narod.ru/tutorials/ds-tutorial.html для нескольких источников света, но для большого количества тормозит. Решил разобраться, и нашел в исходнике с этого же сайта для 200 источников света непонятный метод расчета освещенности:
Код:
program2.bind ();
for ( int i = 0; i < NUM_LIGHTS; i++ )
{
program2.setUniformVector ( "lightPos", camera.mapFromWorld ( lights [i] ) ); //больше в шейдер ничего кроме текстур не передается
glBegin ( GL_QUADS );
glTexCoord2f ( buffer.getWidth (), buffer.getHeight () );
glVertex3fv ( p [0] );
glTexCoord2f ( buffer.getWidth (), 0 );
glVertex3fv ( p [1] );
glTexCoord2f ( 0, 0 );
glVertex3fv ( p [2] );
glTexCoord2f ( 0, buffer.getHeight () );
glVertex3fv ( p [3] );
glEnd ();
}
program2.unbind ();
Получается что NUM_LIGHTS раз отрисовывается один и тот же прямоугольник, каждый раз используются новые координаты для света.
Я так понимаю, что в итоге должен получиться один прямоугольник с (NUM_LIGHTS-1) ' ым источником света. Но в ехе отображаются все источники света - все как и должно быть (сам я компилировать не могу, так как нет нужных библиотек).
Вот их шейдр, в котором видно, что расчет происходит только для ОДНОГО источника света
Код:
#extension GL_ARB_texture_rectangle: enable
varying vec3 pos;
uniform vec3 lightPos;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect colorMap;
#define MAX_DIST 1.5
float atten ( float d ) // compute distance attenuation factor, 0 -> 1, MAX_DIST -> 0
{
const float offs0 = 1.0;
const float offs1 = 1.0 / (1.0 + MAX_DIST);
const float scale = 1.0 / (offs0 - offs1);
return scale * ( 1.0 / (1.0 + d) - offs1 );
}
void main (void)
{
const float zFar = 100.0;
const float zNear = 0.01;
float zb = texture2DRect ( depthMap, gl_FragCoord.xy ).x;
float z = zFar*zNear/(zb * (zFar - zNear) - zFar);
vec3 n = 2.0*(texture2DRect ( normalMap, gl_FragCoord.xy ).xyz - vec3 ( 0.5) );
vec3 c = texture2DRect ( colorMap, gl_FragCoord.xy ).xyz;
vec3 pp = pos * z / pos.z;
vec3 ll = lightPos - pp;
float d = length ( ll );
if ( d > MAX_DIST ) // too far away
discard;
float k = atten ( d );
vec3 l = ll / d;
vec3 v = normalize ( -pp );
vec3 h = normalize ( l + v );
float diff = max ( 0.0, dot ( l, n ) );
float spec = pow ( max ( 0.0, dot ( h, n ) ), 40.0 );
gl_FragColor = k * vec4 ( diff * c + vec3 ( spec ), 1.0 );
}
Не понимаю как вообще может работать такой метод !
Я сделал освещение для нескольких источников, передавая все NUM_LIGHTS источников света в шейдр, и там все рассчитывал, а тут не понятно...
Попробовал сделать тоже самое в своей игре, но как я и предполагал отрисовывается прямоугольник с учетом последнего источника света.