PMG

Форумы по созданию игр
Текущее время: 27 апр 2024 01:09

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 29 дек 2009 21:30 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
У меня снова вопрос. Сделал 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 источников света в шейдр, и там все рассчитывал, а тут не понятно...
Попробовал сделать тоже самое в своей игре, но как я и предполагал отрисовывается прямоугольник с учетом последнего источника света.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 30 дек 2009 16:51 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
ага, кажется понял как это работает, там в начале был glBlend. Вот полный код
Код:
void display ()
{
   GLenum   buffers [] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };   
   buffer.bind ();
   glDrawBuffers ( 2, buffers );   
   reshape ( buffer.getWidth (), buffer.getHeight () );   
       glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
   program1.bind ();
   camera.apply ();   
   displayBoxes ();

   glEnable           ( GL_TEXTURE_RECTANGLE_ARB );
   glReadBuffer       ( GL_COLOR_ATTACHMENT0_EXT );
   glActiveTextureARB ( GL_TEXTURE2_ARB );
   glBindTexture      ( GL_TEXTURE_RECTANGLE_ARB, depthMap );
   glCopyTexImage2D   ( GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT, 0, 0, 512, 512, 0 );   
   program1.unbind ();
   buffer.unbind   ();   

   glClear     ( GL_COLOR_BUFFER_BIT );
   glEnable    ( GL_BLEND );
   glBlendFunc ( GL_ONE, GL_ONE );   

   Vector3D   p [4];
   camera.getPlanePolyForZ ( 1, p );   
   glDisable          ( GL_DEPTH_TEST );
   glDepthMask        ( GL_FALSE );
   glActiveTextureARB ( GL_TEXTURE2_ARB );
   glBindTexture      ( GL_TEXTURE_RECTANGLE_ARB, depthMap );
   glActiveTextureARB ( GL_TEXTURE1_ARB );
   glBindTexture      ( GL_TEXTURE_RECTANGLE_ARB, buffer.getColorBuffer ( 1 ) );
   glActiveTextureARB ( GL_TEXTURE0_ARB );
   glBindTexture      ( GL_TEXTURE_RECTANGLE_ARB, buffer.getColorBuffer ( 0 ) );    
   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 ();   
   glDisable   ( GL_BLEND );
   glEnable    ( GL_DEPTH_TEST );
   glDepthMask ( GL_TRUE );   
   glActiveTextureARB ( GL_TEXTURE0_ARB );   
    glutSwapBuffers ();
}

Но тогда вопрос такой: что лучше использовать в данном случае - glBlend или написать свой шейдр в который буду передавать две текстуры сцены: обычную и состоящую из прозрачных объектов?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 23 янв 2010 21:51 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
MagicWolf, у меня проблема с декалями и deferred shading. Я использую 3 буфера: 1 - координаты точек, 2 - карта нормалей+светимости, 3 - карта с обычными текстурами. Если применять glBlend, то смешивание применяется только к третьему буферу т.к. в него отрисовываются текстуры у которых есть альфа канал. Как можно это исправить? Можно конечно в каждую текстуру с картами нормалей и картой светимости для декалей встроить альфа канал, но может есть другой вариант? Вот код на всякий случай
Код:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, first_fbo);   
GLenum buffers [3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2} ;
glDrawBuffers (3, buffers) ;
//обычные модели
....
//декали
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE4_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, decalsTGA[0]);
for(int i=0;i<sdecalsnum;i++)
    sdecals[i].draw();


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 24 янв 2010 12:09 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Со шрейдерами таки не работал...

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 18 дек 2010 12:26 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
Не хочу начинать новую тему, поэтому спрошу здесь:
Сразу после загрузки карты (всех моделей и текстур, компиляции шейдеров, и начальных вычислений) начинаю отрисовывать основной цикл и получаю 1-5 фпс в начале, и в течении 5 секунд происходит плавное увеличение фпс до 15-20, при этом камеру не вращаю и никаких особых(работающих в этом интервале) вычислений нет. По какой причине такое может происходить?
P.S. На других компах этот интервал отличен от моего. Такое впечатление, что в память что-то грузится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 22 дек 2010 10:58 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Да, конечно, такое бывает. Это связано с работой самой винды. Кэш, dll-ки, сама система что-то доделывает... Вылечить можно только небольшой паузой вначале.

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 22 дек 2010 12:15 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
Понятно, ну я так и хотел сначала сделать. Кстати услышал такую версию, что на многих видеокартах сейчас включен режим экономии ресурсов и т.к. в винде особых нагрузок нет, то после запуска игры постепенно увеличивается производительность.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 30 дек 2010 14:52 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
Поменял видяху с GeForce на Radeon и на ней моя игра неправильно отображалась (т.к. использую deferred shading), произвольно цвета менялись при повороте камеры и помехи на экране были, ошибки типа GL_INVALID_OPERATION и т.д., хотя на GeForce все отлично. Целый день искал ошибки, весь код перекапал, но в итоге нашел. Вот главные:
1) Нельзя передавать никакие данные в шейдр, если он выключен:
Код:
glUseProgramObjectARB(0);     
location = glGetUniformLocation(data.first_glsl, "diffMap");
glUniform1i(location, 4);
Конечно эта передача смысла не имеет, но интересно почему из-за нее все неправильно отображается.
2)После использования разных текстурных слоев нужно их убрать:
Код:
glActiveTextureARB ( GL_TEXTURE3_ARB );
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, data.specMap );
glActiveTextureARB ( GL_TEXTURE2_ARB );
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, data.diffMap );

отрисовка

glActiveTexture(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 31 дек 2010 10:28 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Н-да теперь не понятно, почему на GeForce работало.

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 31 дек 2010 18:36 
Не в сети
Опытный

Зарегистрирован: 02 ноя 2008 02:36
Сообщения: 116
Откуда: Kiev
http://www.opengl.org/wiki/GLSL_:_common_mistakes здесь объяснение твоих проблем ;) Нвидиа не везде следует спецификации и разрешает кое-какие вольности...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: glsl
СообщениеДобавлено: 02 янв 2011 13:00 
Не в сети
Опытный
Аватара пользователя

Зарегистрирован: 04 июл 2008 10:11
Сообщения: 144
Откуда: Питер
спасибо, поищу в инете похожие темы. Интересно написано в статье про Dot products, никогда бы не подумал, что это быстрее работает ;)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 63


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB