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
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); |
|
|
|
} |
|
|
|
|