2012-06-26 2 views
1

Я пишу программу GLSL как часть плагина, который запускается внутри майя, трехмерного приложения с закрытым исходным кодом. Мой плагин отображает пользовательскую геометрию в тот же буфер изображений, что и приложение, которое делает его полигональной геометрией по умолчанию. Приложение использует фиксированный конвейер OpenGL для его освещения и затенения, но я использую GLSL для визуализации собственной геометрии и материалов.GLSL gl_LightSource Точечная/направленная/точечная дифференциация

Моя проблема заключается в том, что я хочу подражать поведению фиксированных огней трубопровода в моем шейдере. Приложение определяет огни в форме gl_LightSource, и я хочу, чтобы они имели одинаковое направление, интенсивность и т. Д., Когда они были назначены моей настраиваемой геометрии, которые они имеют при назначении для полигональной геометрии по умолчанию.

Поля, обозначенные как gl_LightSource, четко документированы, но я не могу найти окончательную документацию о том, как фиксированный конвейер интерпретирует эти поля. Существует много примеров того, как кодировать точки/направленные/точечные огни в GLSL, но они, похоже, точно не имитируют фиксированный конвейер. Например, как вы определяете, является ли свет точным, направленным или точечным, если приложение определяет их сочетание? Можно ли обрабатывать смесь типов света без введения чрезмерного разветвления в моем шейдере?

Короче говоря, существует ли какая-либо окончательная документация или пример того, как оценивается конвейер фиксированной функции gl_LightSource?

ответ

2

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

Ну есть ваша первая проблема, потому что «неподвижные огни трубопровода» реализуются в вершинных процессоре , а не на-фрагмента.

Короче говоря, существует ли какая-либо окончательная документация или пример того, как конвейер фиксированной функции оценивает gl_LightSource?

Да. Он называется «Графическая система OpenGL: спецификация». Он доступен для download on the OpenGL Registry; вам нужен профиль совместимости. Раздел 2.13 спецификации совместимости 4.2 охватывает всю математику, используемую для освещения. Просто переведите это в код GLSL.

Обратите внимание, что вы не сможете точно имитировать контур фиксированной функции. То есть, нет никакого способа гарантировать инвариантность освещения на основе шейдеров и фиксированной функции. Вы получите что-то близкое, но не двоично-идентичные значения.

Можно ли обрабатывать смесь типов света без введения чрезмерного разветвления в моем шейдере?

Как вы определяете "чрезмерный"? Вам понадобится разветвление, потому что уравнения освещения OpenGL связаны с условной логикой.

Это, как правило, является причиной того, почему люди не просто переопределяют освещение GL в шейдере. Вы можете быть намного эффективнее, если просто написать GLSL, а не использовать подход, основанный на данных.

+0

Спасибо за ссылку. Я отредактировал свой вопрос и удалил ссылку на фрагмент, я знаю, но не заинтересован в этой разнице. Если бы я мог избежать фиксированного конвейера, я бы, но я работаю в закрытом исходном приложении, так что мои руки связаны. – atb

1

Существует полный исходный код вершинного шейдера, который реализует конвейер фиксированной функции в OpenGL ES 2.0 Programming Guide.(Обратите внимание, что функция трубопровод фиксируется только за вершину освещение, поэтому, пиксельный шейдер не требуется для расчета освещения.)

Я считаю, что OpenGL драйвер использует этот вершинный шейдер внутри, когда он находится в режиме фиксированной функции. Пожалуйста, проверьте главу 8 «Вершинные шейдеры» этой книги.

Он определяет-структуру из света со следующими свойствами;

  1. Положение,
  2. окружающей среды цвет,
  3. диффузный цвет,
  4. Зеркальное Цвет,
  5. Пятно Направление,
  6. затухания Факторы (константа, линейный, quaratic),
  7. Пятно экспонент ,
  8. пятно Граничная Угол,
  9. ComputeDistanceAttanuation (BOOL)

и, каждый источник света обрабатывается в функции, lighting_equation().

0

Вот что я придумал на основе документа OpenGL Спецификация:

#version 410 compatibility 

vec3 incedentLight (in gl_LightSourceParameters light, in vec3 position) 
{ 
    if (light.position.w == 0) { 
     return normalize (-light.position.xyz); 
    } else { 
     vec3 offset = position - light.position.xyz; 
     float distance = length (offset); 
     vec3 direction = normalize (offset); 
     float intensity; 
     if (light.spotCutoff <= 90.) { 
      float spotCos = dot (direction, normalize (light.spotDirection)); 
      intensity = pow (spotCos, light.spotExponent) * 
        step (light.spotCosCutoff, spotCos); 
     } else { 
      intensity = 1.; 
     } 
     intensity /= light.constantAttenuation + 
       light.linearAttenuation * distance + 
       light.quadraticAttenuation * distance * distance; 
     return intensity * direction; 
    } 
} 

Из того, что я понимаю, о GLSL разветвление должно быть достаточно эффективным, поскольку он зависит только от однородных переменных.

Смежные вопросы