没有看到SpotLight - OpenGL

时间:2014-11-23 06:03:18

标签: c++ opengl glsl

我正在OpenGL的聚光灯下做一个项目。我想我正确编写了代码但是我无法在输出中看到一个圆点。非常感谢您的帮助。在这里,我正在编写片段着色器文件和光定义。

fragmentShader.fs

#version 330

in vec3 N; // interpolated normal for the pixel
in vec3 v; // interpolated position for the pixel 

// Uniform block for the light source properties
layout (std140) uniform LightSourceProp {
    // Light source position in eye space (i.e. eye is at (0, 0, 0))
    uniform vec4 lightSourcePosition;

    uniform vec4 diffuseLightIntensity;
    uniform vec4 specularLightIntensity;
    uniform vec4 ambientLightIntensity;

    // for calculating the light attenuation 
    uniform float constantAttenuation;
    uniform float linearAttenuation;
    uniform float quadraticAttenuation;

    // Spotlight direction
    uniform vec3 spotDirection;
    uniform float  cutOffExponent;
    // Spotlight cutoff angle
    uniform float spotCutoff;
};

// Uniform block for surface material properties
layout (std140) uniform materialProp {
    uniform vec4 Kambient;
    uniform vec4 Kdiffuse;
    uniform vec4 Kspecular;
    uniform float shininess;
};

out vec4 color;

// This fragment shader is an example of per-pixel lighting.
void main() {

    // Now calculate the parameters for the lighting equation:
    // color = Ka * Lag + (Ka * La) + attenuation * ((Kd * (N dot L) * Ld) + (Ks * ((N dot HV) ^ shininess) * Ls))
    // Ka, Kd, Ks: surface material properties
    // Lag: global ambient light (not used in this example)
    // La, Ld, Ls: ambient, diffuse, and specular components of the light source
    // N: normal
    // L: light vector
    // HV: half vector
    // shininess
    // attenuation: light intensity attenuation over distance and spotlight angle

    vec3 lightVector;
    float attenuation = 1.0; 
    float se;


    // point light source
    lightVector = normalize(lightSourcePosition.xyz - v);

    //Calculate Spoteffect
    // calculate attenuation    


 float angle = dot( normalize(spotDirection),
                 normalize(lightVector));
    angle = max(angle,0);   

   // Test whether vertex is located in the cone
   if(acos (angle) > radians(5))
 { 

  float distance = length(lightSourcePosition.xyz - v);
   angle = pow(angle,2.0);

 attenuation = angle / (constantAttenuation + (linearAttenuation * distance) 
        +(quadraticAttenuation * distance * distance));

           //calculate Diffuse Color  
   float NdotL = max(dot(N,lightVector), 0.0);

   vec4 diffuseColor = Kdiffuse * diffuseLightIntensity * NdotL;

   // calculate Specular color. Here we use the original Phong illumination model. 
   vec3 E = normalize(-v); // Eye vector. We are in Eye Coordinates, so EyePos is (0,0,0)  

   vec3 R = normalize(-reflect(lightVector,N)); // light reflection vector

   float RdotE = max(dot(R,E),0.0);

   vec4 specularColor = Kspecular * specularLightIntensity * pow(RdotE,shininess);

   // ambient color
   vec4 ambientColor = Kambient * ambientLightIntensity;

  color = ambientColor + attenuation * (diffuseColor + specularColor);   

  }   
   else
       color = vec4(1,1,0,1); // lit (yellow)


}

main.cpp中的灯光定义

struct SurfaceMaterialProp {
    float Kambient[4]; //ambient component
    float Kdiffuse[4]; //diffuse component
    float Kspecular[4]; // Surface material property: specular component
    float shininess; 
};

SurfaceMaterialProp surfaceMaterial1 = {
    {1.0f, 1.0f, 1.0f, 1.0f},  // Kambient: ambient coefficient
    {1.0f, 0.8f, 0.72f, 1.0f},  // Kdiffuse: diffuse coefficient
    {1.0f, 1.0f, 1.0f, 1.0f},  // Kspecular: specular coefficient
    5.0f // Shininess
};

struct LightSourceProp {
    float lightSourcePosition[4]; 
    float diffuseLightIntensity[4];
    float specularLightIntensity[4];
    float ambientLightIntensity[4];
    float constantAttenuation; 
    float linearAttenuation;
    float quadraticAttenuation;
    float spotlightDirection[4];
    float spotlightCutoffAngle;
    float  cutOffExponent;
};

LightSourceProp lightSource1 = {
    { 0.0,400.0,0.0, 1.0 },  // light source position
    {1.0f, 0.0f, 0.0f, 1.0f},  // diffuse light intensity
    {1.0f, 0.0f, 0.0f, 1.0f},  // specular light intensity
    {1.0f, 0.2f, 0.0f, 1.0f}, // ambient light intensity
    1.0f, 0.5, 0.1f,   // constant, linear, and quadratic attenuation factors
    {0.0,50.0,0.0},  // spotlight direction
    {5.0f}, // spotlight cutoff angle (in radian)
    {2.0f} // spotexponent
    };

1 个答案:

答案 0 :(得分:2)

C ++代码中LightSourceProp结构的几个成员的顺序与统一块中的结构顺序不同。

统一区块的最后两名成员:

    uniform float cutOffExponent;
    uniform float spotCutoff;
};

C ++ struct的最后两个成员:

    float spotlightCutoffAngle;
    float  cutOffExponent;
};

交换这两个值。

此外,截止角看起来非常大:

{5.0f}, // spotlight cutoff angle (in radian)

那是一个286度的角度,这不是一个聚光灯。对于实际的聚光灯,您可能需要更小的内容,例如0.1f0.2f

可能会给你意想不到的结果的另一个方面是你有很多环境强度:

{1.0f, 1.0f, 1.0f, 1.0f},  // Kambient: ambient coefficient
...
{1.0f, 0.2f, 0.0f, 1.0f}, // ambient light intensity

根据您在着色器代码中使用这些值的方式,您的颜色可能会仅仅从环境强度饱和,并且您不会从其他条款中获得任何可见的贡献。光源和材料。由于环境强度是恒定的,这将导致整个几何体的颜色完全平坦。