63 lines
1.5 KiB
GLSL
63 lines
1.5 KiB
GLSL
#version 440
|
|
|
|
in vec3 f_color;
|
|
out vec4 FragColors;
|
|
|
|
uniform vec3 Kd;
|
|
uniform vec3 Ka;
|
|
uniform vec3 Ks;
|
|
uniform float Shininess;
|
|
|
|
uniform vec4 LightLocation;
|
|
uniform vec3 LightIntensity;
|
|
|
|
uniform vec4 LightDirection;
|
|
uniform float Exponent;
|
|
uniform float Cutoff;
|
|
uniform float InnerCutoff;
|
|
|
|
in vec3 fNormal;
|
|
in vec3 pos;
|
|
|
|
const float a = 1.0f;
|
|
const float b = 0.01f;
|
|
const float c = 0.001f;
|
|
|
|
void main()
|
|
{
|
|
|
|
vec3 LightDir = LightDirection.xyz - LightLocation.xyz;
|
|
|
|
vec3 L = LightLocation.xyz - pos;
|
|
float d = length(L);
|
|
L = normalize(L);
|
|
|
|
float attenuation = 1.0f / (a + b * d + c * pow(d, 2));
|
|
float angle = acos(dot(-L, normalize(LightDir))); // radian
|
|
float spotAttenuation = 1.0f;
|
|
if (angle < radians(InnerCutoff))
|
|
spotAttenuation = 1.0f;
|
|
else
|
|
{
|
|
// pos is outside the spot's inner cutoff
|
|
float SpotDot = dot(-L, normalize(LightDir));
|
|
float spotValue = smoothstep(cos(radians(Cutoff)), cos(radians(InnerCutoff)), SpotDot);
|
|
spotAttenuation = pow(spotValue, Exponent);
|
|
}
|
|
attenuation *= spotAttenuation;
|
|
|
|
vec3 N = normalize(fNormal);
|
|
vec3 V = normalize(-pos);
|
|
vec3 H = normalize(V + L);
|
|
|
|
float dotNL = max(dot(L, N), 0.0); // for diffuse
|
|
float dotHN = max(dot(H, N), 0.0); // for spec
|
|
float pf = pow(dotHN, Shininess); // for spec
|
|
|
|
vec3 ambient = Ka * LightIntensity * attenuation;
|
|
vec3 diffuse = Kd * LightIntensity * dotNL * attenuation;
|
|
vec3 specular = Ks * LightIntensity * pf * attenuation;
|
|
|
|
FragColors = vec4(diffuse + specular + ambient, 1);
|
|
}
|