CCCPaste

shader.frag

#version 460 core

in vec4 col;
in vec2 texCoord;
in vec3 Normal;
in vec3 fragPos;

out vec4 color;

// Should be same as Utilities.h header file
const int MAX_POINT_LIGHTS = 3;
const int MAX_SPOT_LIGHTS = 3;

struct Light {
vec3 colour;
float ambientIntensity;
float diffuseIntensity;
};

struct DirectionalLight {
Light base;
vec3 direction;
};

struct PointLight {
Light base;
vec3 position;
float constant;
float linear;
float exponent;
};

struct SpotLight {
PointLight base;
vec3 direction;
float edge;
};

struct Material {
float specularIntensity;
float shininess;
};

uniform int pointLightCount;
uniform int spotLightCount;

// Lights
uniform DirectionalLight directionalLight;
uniform PointLight pointLight[MAX_POINT_LIGHTS];
uniform SpotLight spotLight[MAX_SPOT_LIGHTS];

// Textures
uniform sampler2D theTexture;

// Materials
uniform Material material;

// Eye Position
uniform vec3 eyePosition;

vec4 calcLightByDirection(Light light, vec3 direction) {
// Ambient Light
vec4 ambientColour = vec4(light.colour, 1.0f) * light.ambientIntensity;

// Diffuse Light
// Getting the cosine of angle between two vectors
float diffuseFactor = max(dot(normalize(Normal), normalize(direction)), 0.0f);
vec4 diffuseColour = vec4(light.colour * light.diffuseIntensity * diffuseFactor, 1.0f);

// Specular Light
vec4 specularColour = vec4(0, 0, 0, 0);

// If no diffuse, then no specular
if(diffuseFactor > 0.0f) {
vec3 fragToEye = normalize(eyePosition - fragPos);
vec3 reflectedVertex = normalize(reflect(direction, normalize(Normal)));

float specularFactor = dot(fragToEye, reflectedVertex);

if(specularFactor > 0.0f) {
specularFactor = pow(specularFactor, material.shininess);
specularColour = vec4(light.colour * material.specularIntensity * specularFactor, 1.0f);
}
}

return (ambientColour + diffuseColour + specularColour);
}

vec4 calcDirectionalLight() {
return calcLightByDirection(directionalLight.base, directionalLight.direction);
}

vec4 calcPointLightsBase(PointLight pLight) {
// Calculating Direction of our Point Lights
// Getting direction from light to fragment
vec3 direction = fragPos - pLight.position;
float distance = length(direction);

direction = normalize(direction);

vec4 colour = calcLightByDirection(pLight.base, direction);

float attenuation = pLight.exponent * distance * distance +
pLight.linear * distance +
pLight.constant;

return (colour / attenuation);
}

vec4 calcSpotLightsBase(SpotLight sLight) {
// Getting Direction
vec3 rayDirection = normalize(fragPos - sLight.base.position);
float slFactor = dot(rayDirection, sLight.direction);

// If we are withing range
if(slFactor > sLight.edge) {
vec4 colour = calcPointLightsBase(sLight.base);

return colour * (1.0f - (1.0 - slFactor) * (1.0f/(1.0f - sLight.edge)));
}

else {
return vec4(0, 0, 0, 0);
}
}

vec4 calcPointLights() {
vec4 totalColour = vec4(0, 0, 0, 0);

for(int i = 0; i < pointLightCount; i++) {
totalColour += calcPointLightsBase(pointLight[i]);
}

return totalColour;
}

vec4 calcSpotLights() {
vec4 totalColour = vec4(0, 0, 0, 0);

for(int i = 0; i < spotLightCount; i++) {
totalColour += calcSpotLightsBase(spotLight[i]);
}

return totalColour;
}

void main() {
vec4 finalColour = calcDirectionalLight();
finalColour += calcPointLights();
finalColour += calcSpotLights();

color = texture(theTexture, texCoord) * finalColour;
}