OpenGL 3.3中的多纹理和多灯

时间:2014-08-24 17:29:31

标签: c++ opengl glsl fragment-shader vertex-shader

我有一个城堡项目,我发送一个灯光和一个材料到着色器。我想添加一个光和纹理,但我不知道如何在着色器中做到这一点。 这是我的片段着色器:

#version 130        

out vec4 pixelColor; 

in vec4 l;
in vec4 n;
in vec4 v;

uniform sampler2D textureMap0, textureMap1;
in vec2 iTexCoord;
in vec2 iTexCoord2;
uniform vec4 dragi1; 
uniform vec4 dragi2;
uniform vec4 dragi3;
uniform float polysk;

uniform vec4 Light0ambient;
uniform vec4 Light0diffuse;
uniform vec4 Light0specular;
uniform vec4 Light0position;

uniform vec4 Material0emission;
uniform vec4 Material0ambient;
uniform vec4 Material0diffuse;
uniform vec4 Material0specular;
uniform float Material0shininess;

void main(void) {

  vec4 ml=normalize(l);
  vec4 mn=normalize(n);
  vec4 mv=normalize(v);
  vec4 mr=reflect(-ml,mn);

  float nl=max(dot(ml,mn),0);
  float rv=pow(max(dot(mr,mv),0),Material0shininess);

  pixelColor=Light0ambient*Material0ambient+Light0diffuse*Md*vec4(nl,nl,nl,1)+Light0specular*Material0specular*vec4(rv,rv,rv,0);
}

这是我的顶点着色器:

#version 130

uniform mat4 P;
uniform mat4 V;
uniform mat4 M;

in vec4 vertex;             
in vec4 normal;            
in vec2 texCoord;           

out vec4 l;                 
out vec4 n;                 
out vec4 v;                 

out vec2 iTexCoord;
out vec2 iTexCoord2;

uniform vec4 Light0position;

void main(void) {
    gl_Position=P*V*M*vertex;

    l=normalize(V*(Light0position-M*vertex)); 
    n=normalize(V*M*normal); 
    v=normalize(vec4(0,0,0,1)-V*M*vertex);

    iTexCoord = texCoord;
    iTexCoord2 = (n.xy + 1)/2;
}

这很简单吗? 还有一个问题,如何创造聚光灯?我能用简单的方法做到这一点吗?

1 个答案:

答案 0 :(得分:1)

如果要在着色器中使用多个灯光,通常将所有灯光和材质数据存储在数组中,并使用或不使用GLSL函数在一个大型for循环中处理每个灯光。

例如,您可以创建一个light和一个material结构,并创建这样的结构的统一数组:

struct Light {
    vec4 position;    
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
};

struct Material {
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    vec4 emission;
    float shininess;
}; 

uniform Light lights[4]; // Use 4 lights
uniform Material materials[2]; // Use 2 materials

然后片段着色器的结构可能如下所示:

out vec4 color;

void main()
{
    // define an output color value
    vec3 output;
    // calculate lighting value per light source
    for(int i = 0; i < 4; i++)
        outout += someFunctionToCalculateLight(lights[i], materials[0]);
    color = vec4(output, 1.0);
}  

在这种情况下,创建了一个函数来计算生成的光源颜色光源并添加到最终的output颜色。这通常是您使用多个灯光的方式。请注意,这是一个非常基本的例子。

另外,如果您想知道如何创建一个聚光灯,那么最好关注那些有很多可以在网上找到的主题的教程,而不是在这里询问。

一些教程: