forkkmuopengl/BaseGLProject/spotlight.frag

76 lines
1.8 KiB
GLSL

#version 440
in vec3 f_color;
out vec4 FragColors;
uniform vec3 Kd;
uniform vec3 Ka;
uniform vec3 Ks;
uniform float Shininess;
struct LightInfo {
vec4 Position;
vec3 Intensity;
float SpotCutoff;
float SpotInnerCutoff;
float SpotExponent;
vec3 SpotDirection;
};
uniform LightInfo Light[64];
uniform int LightCount;
in vec3 fNormal;
in vec3 pos;
void main()
{
vec3 ambient_sum;
vec3 diffuse_sum;
vec3 specular_sum;
vec3 ambient;
float D;
float attenuation;
for (int i=0; i<LightCount; i++)
{
D = distance(Light[i].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
float SpotAttenuation = 1.0;
vec spotDot = dot(Light[i].SpotCutoff, Light[i].SpotInnerCutoff);
float theta = dot(L, normalize(Light[i].SpotDirection)); //Angle between the light direction and the fragment-light vector.
float phi = ; // Angle between the light direction and the inner cutoff.
if (theta < Light[i].SpotInnerCutoff)
{
SpotAttenuation = 1.0; //No change in the attenuation
}
else
{
//Fragment is outside the Cone
//Interpolate between cos(Innercutoff )and cos(cutoff) with cos(theta)
float Spot = smoothstep(cos(Light[i].SpotCutoff),cos(Light[i].SpotInnerCutoff),cos(theta));
SpotAttenuation = pow(Spot, Light[i].SpotExponent);
}
attenuation *= SpotAttenuation;
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * attenuation;
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess) * attenuation;
ambient_sum += ambient;
diffuse_sum += diffuse;
specular_sum += specular;
}
FragColors = vec4(diffuse_sum + specular_sum + ambient_sum / LightCount, 1);
}