Программа шейдера для шейдера Vertex + Fragment

Я изучаю руководство, в котором используется этот шейдер:

struct VSInput
{
  vec3 Position;
  vec2 TexCoord;
  vec3 Normal;  
};

interface VSOutput
{
  vec3 WorldPos;
  vec2 TexCoord;
  vec3 Normal;  
};


uniform mat4 gWVP;
uniform mat4 gWorld;

shader VSmain(in VSInput VSin:0, out VSOutput VSout)         
{                   
  gl_Position = gWVP * vec4(VSin.Position, 1.0);
  VSout.TexCoord   = VSin.TexCoord;                  
  VSout.Normal     = (gWorld * vec4(VSin.Normal, 0.0)).xyz;   
  VSout.WorldPos   = (gWorld * vec4(VSin.Position, 1.0)).xyz; 
};


struct FSOutput
{                   
  vec3 WorldPos;    
  vec3 Diffuse;     
  vec3 Normal;      
  vec3 TexCoord;    
};


uniform sampler2D gColorMap;                

shader FSmain(in VSOutput FSin, out FSOutput FSout)                                 
{                                           
FSout.WorldPos = FSin.WorldPos;                 
FSout.Diffuse  = texture(gColorMap, FSin.TexCoord).xyz; 
FSout.Normal   = normalize(FSin.Normal);                    
FSout.TexCoord = vec3(FSin.TexCoord, 0.0);              
};

program GeometryPass
{
  vs(410)=VSmain();
  fs(410)=FSmain();
};

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

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

Также, насколько я понимаю, для этого шейдера требуется ядро ​​OpenGL 4.1.0. Действительно ли это необходимо или есть другой способ достичь того же результата, используя более низкий уровень (скажем, 3.3)?


person Massimo Callegari    schedule 02.05.2013    source источник
comment
Это недействительный GLSL. Это близко, но в нем есть несколько забавных дополнительных вещей, которые должны быть связаны с конкретной средой, для которой он был написан.   -  person Ben Voigt    schedule 03.05.2013
comment
Он загружен с помощью glfx, и я не хочу перетаскивать его в свой код. Однако должен быть способ вернуться к действительному и чистому коду GLSL. Я просто не знаю как :( Любая помощь?   -  person Massimo Callegari    schedule 03.05.2013


Ответы (1)


Это похоже на вариант CgFX с использованием кода GLSL с добавленным синтаксисом Cg. Чтобы преобразовать его в действительный GLSL, вам необходимо разделить его на отдельные вершинные и фрагментные шейдеры, переименовать точки входа для каждого в main и переместить аргументы в точку входа так, чтобы они были несколькими глобальными переменными, а не структурами (переименование вещей, чтобы избежать коллизий.) Самая тонкая деталь - это семантика :0 входного аргумента VSmain, которая становится квалификаторами layout на соответствующих in глобальных объектах.

Таким образом, вершинный шейдер становится:

#version 410 compatibility
//struct VSInput
//{
  in layout(location = 0) vec3 Position;
  in layout(location = 1) vec2 in_TexCoord;
  in layout(location = 2) vec3 in_Normal;  
//};

//interface VSOutput
//{
  out vec3 WorldPos;
  out vec2 TexCoord;
  out vec3 Normal;  
//};


uniform mat4 gWVP;
uniform mat4 gWorld;

//shader VSmain(in VSInput VSin:0, out VSOutput VSout)
main()     
{                   
  gl_Position = gWVP * vec4(Position, 1.0);
  TexCoord    = in_TexCoord;                  
  Normal      = (gWorld * vec4(in_Normal, 0.0)).xyz;   
  WorldPos    = (gWorld * vec4(Position, 1.0)).xyz; 
}

Аналогично трансформируется фрагментный шейдер.

person Chris Dodd    schedule 02.05.2013