Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 330 core
- #extension GL_ARB_gpu_shader_fp64 : enable
- in VS_OUT {
- vec2 TexCoord;
- vec3 FragPos;
- mat3 TBN;
- vec4 FragPosLightSpace;
- vec4 FragSpotLightSpaceMatrix;
- } fs_in;
- out vec4 fragColor;
- struct Material {
- sampler2D diffuseMap;
- sampler2D specularMap;
- sampler2D normalMap;
- sampler2D shadowMap;
- sampler2D spotLightShadowMap;
- float shininess;
- };
- struct DirLight {
- vec3 direction;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- vec3 color;
- };
- struct SpotLight {
- vec3 color;
- vec3 position;
- vec3 direction;
- float cutOff;
- float outerCutOff;
- float constant;
- float linear;
- float quadratic;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- };
- uniform vec3 viewPos;
- uniform DirLight dirLight;
- uniform SpotLight spotLight;
- uniform Material material;
- double ShadowCalculation(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir, sampler2D shadowMap)
- {
- vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
- projCoords = projCoords * 0.5 + 0.5;
- if(projCoords.z > 1.0)
- return 0.0;
- double closestDepth = texture(shadowMap, projCoords.xy).r;
- double currentDepth = projCoords.z;
- double bias = max(0.005 * (1.0 - dot(normal, lightDir)), 0.001);
- double shadow = 0.0;
- vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
- for(int x = -1; x <= 1; ++x)
- {
- for(int y = -1; y <= 1; ++y)
- {
- double pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
- shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
- }
- }
- shadow /= 9.0;
- return shadow;
- }
- dvec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
- {
- vec3 color = texture(material.diffuseMap, fs_in.TexCoord).rgb;
- vec3 lightDir = normalize(-light.direction);
- vec3 halfwayDir = normalize(lightDir + viewDir); //Blinn
- float diff = max(dot(normal, lightDir), 0.0);
- vec3 reflectDir = reflect(-lightDir, normal);
- float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess); //Blinn
- dvec3 ambient = light.ambient * color;
- dvec3 diffuse = light.diffuse * diff * color;
- dvec3 specular = light.specular * spec * vec3(texture(material.specularMap, fs_in.TexCoord));
- double shadow = ShadowCalculation(fs_in.FragPosLightSpace, normal, lightDir, material.shadowMap);
- return (ambient + (1.0 - shadow) * (diffuse + specular));
- }
- dvec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
- {
- //vec3 tangentLightPos = fs_in.TBN * light.position;
- vec3 lightDir = normalize(light.position - fragPos);
- vec3 halfwayDir = normalize(lightDir + viewDir); //Blinn
- float diff = max(dot(normal, lightDir), 0.0);
- vec3 reflectDir = reflect(-lightDir, normal);
- float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess); //Blinn
- float distance = length(light.position - fragPos);
- float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
- float theta = dot(lightDir, normalize(-light.direction));
- float epsilon = light.cutOff - light.outerCutOff;
- float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
- dvec3 ambient = light.ambient * vec3(texture(material.diffuseMap, fs_in.TexCoord));
- dvec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuseMap, fs_in.TexCoord));
- dvec3 specular = light.specular * spec * vec3(texture(material.specularMap, fs_in.TexCoord));
- ambient *= attenuation * intensity;
- diffuse *= attenuation * intensity;
- specular *= attenuation * intensity;
- double shadow = ShadowCalculation(fs_in.FragSpotLightSpaceMatrix, normal, lightDir, material.spotLightShadowMap);
- return (ambient + (1.0 - shadow) * (diffuse + specular));
- }
- void main()
- {
- vec3 normal = vec3(texture(material.normalMap, fs_in.TexCoord).rgb);
- normal = normal * 2.0 - 1.0;
- normal = normalize(normal);
- //check if drawing a mirrored fragment
- vec3 tangent = fs_in.TBN[0];
- vec3 bitangent = fs_in.TBN[1];
- vec3 calcN = cross(tangent, bitangent);
- float normalsAligned = dot(calcN, fs_in.TBN[2]);
- if (normalsAligned < 0) {
- tangent =-tangent;
- mat3 TBN_CORRECT = fs_in.TBN;
- TBN_CORRECT[0] = tangent;
- normal = normalize(TBN_CORRECT * normal);
- }
- else {
- normal = normalize(fs_in.TBN * normal);
- }
- vec3 viewDir = normalize(viewPos - fs_in.FragPos);
- dvec3 result = CalcDirLight(dirLight, normal, viewDir) * dirLight.color;
- result += CalcSpotLight(spotLight, normal, fs_in.FragPos, viewDir) * spotLight.color;
- fragColor = vec4(result, 1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement