A WIP 3D game engine in C++ using OpenGL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
3.5 KiB

#version 330 core
out vec4 LFragment;
in vec3 Normal;
in vec3 FragPos;
in mat3 TBN;
in vec3 theTexCoord;
uniform vec3 cameraPosition;
uniform samplerCube skybox;
float gamma = 2.2;
struct Material {
sampler2D texture_diffuse1;
sampler2D texture_diffuse2;
sampler2D texture_diffuse3;
float shininess;
};
#define DIRECTIONAL_LIGHT 0
#define POINT_LIGHT 1
#define SPOT_LIGHT 2
struct Light {
int type;
vec3 direction;
vec3 position;
float angle_cutoff;
float outer_angle_cutoff;
vec3 ambient;
vec3 diffuse;
vec3 specular;
bool attenuate;
vec3 attenuation;
};
#define MAX_LIGHTS 10
uniform Light lights[MAX_LIGHTS];
uniform int num_lights;
uniform Material material;
vec4
reflection(vec3 norm)
{
vec3 reflectiveness = material.specular * material.shininess / 50;
vec3 I = normalize(FragPos - cameraPosition);
vec3 R = reflect(I, norm);
return texture(skybox, R) * (material.shininess / 90);
}
float
spotlight(int i, vec3 lightDir)
{
float theta = dot(lightDir, normalize(-lights[i].direction));
float epsilon = lights[i].angle_cutoff - lights[i].outer_angle_cutoff;
float intensity = clamp((theta - lights[i].outer_angle_cutoff)/epsilon, 0.0, 1.0);
return intensity;
}
float
attenuation(int i)
{
float dist = length(lights[i].position - FragPos);
// for no gamma correction
//float attenuation = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y *
//dist + lights[i].attenuation.y * (dist * dist));
// for gamma correction
float attenuation = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y *
dist + lights[i].attenuation.y * (dist));
return attenuation;
}
vec3
specular(int i, vec3 lightDir, vec3 norm)
{
float spec = max(dot(normalize(cameraPosition - FragPos), reflect(-lightDir, norm)), 0.0);
spec = pow(spec, material.shininess);
vec3 specular = lights[i].specular * (spec *
vec3(texture(material.texture_specular1, vec2(theTexCoord))));
return specular;
}
vec3
diffuse(int i, vec3 lightDir, vec3 norm)
{
float diff_val = max(dot(norm, lightDir), 0.0);
vec3 diffuse = lights[i].diffuse * (diff_val * material.diffuse);
return diffuse;
}
void
main()
{
vec3 endResult = vec3(0);
// normal
vec3 norm;
norm = texture(material.texture_normal1, vec2(theTexCoord)).rgb;
norm = norm * 2.0 - 1.0;
norm = normalize(TBN * norm);
for (int i = 0; i < num_lights; i++) {
vec3 ambient = lights[i].ambient * material.ambient;
// diffuse
vec3 lightDir = vec3(0);
if (lights[i].type == POINT_LIGHT || lights[i].type == SPOT_LIGHT) {
lightDir = normalize(lights[i].position - FragPos);
} else if (lights[i].type == DIRECTIONAL_LIGHT) {
lightDir = normalize(-lights[i].direction);
}
vec3 diffuse = diffuse(i, lightDir, norm);
vec3 specular = specular(i, lightDir, norm);
vec3 result = ambient;
float intensity = 1.0;
if (lights[i].type == SPOT_LIGHT) {
intensity = spotlight(i, lightDir);
}
result = ambient + (diffuse + specular) * intensity;
if (lights[i].attenuate) {
result *= attenuation(i);
}
endResult += result;
}
vec4 parta = (vec4(endResult, 1.0)) * texture(material.texture_diffuse1, vec2(theTexCoord));
LFragment = parta;
// gamma correction
// LFragment.rgb = pow(parta.rgb, vec3(1.0/gamma));
// LFragment = vec4(norm, 1);
}