| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #version 450
- struct PointLight
- {
- vec4 position; // w is radius
- vec4 color; // w is intensity
- };
- layout (set = 0, binding = 0) uniform GlobalUBO
- {
- // MATRICES
- mat4 view;
- mat4 viewInverse;
- mat4 viewProjection;
- // LIGHTING
- vec4 globalLightDirection;
- vec4 ambientLighting;
- // POINT LIGHTS
- PointLight pointLights[8];
- int numLights;
- } ubo;
- // SAMPLERS
- layout (set = 0, binding = 1) uniform samplerCube samplerCubeMap;
- layout (set = 1, binding = 0) uniform sampler2D samplerColorMap;
- layout (set = 1, binding = 1) uniform sampler2D samplerNormalMap;
- layout (set = 1, binding = 2) uniform sampler2D samplerOcclusionMap;
- layout (set = 1, binding = 3) uniform sampler2D samplerMetallicRoughness;
- // CONSTANTS
- layout (constant_id = 0) const bool ALPHA_MASK = false;
- layout (constant_id = 1) const float ALPHA_MASK_CUTOFF = 0.0f;
- // FRAGMENT INPUT
- layout (location = 0) in struct FS_IN
- {
- vec3 fragPos;
- vec2 texcoord;
- mat3 TBN;
- } fs_in;
- // OUT COLOR
- layout (location = 0) out vec4 outFragColor;
- vec3 calculate_diffuse(vec3 N, vec3 L, vec3 C)
- {
- float diffuse_strength = max(dot(N, L), 0);
- // HALF-LAMBERT
- diffuse_strength = pow(diffuse_strength * 0.5f + 0.5f, 2);
- diffuse_strength = max(diffuse_strength, 0.f);
- return C * diffuse_strength;
- }
- vec3 calculate_specular(vec3 N, vec3 V, vec3 L, vec3 C)
- {
- V = normalize(V);
- L = normalize(L);
- // HALF VECTOR
- vec3 halfVector = normalize(L + V);
- // Specularity
- float shininess = 16.f;
- float specularity = pow(max(dot(N, halfVector), 0.f), shininess * shininess);
- return C * specularity;
- }
- vec3 calculate_fresnel(vec3 N, vec3 V, vec3 C)
- {
- float fresnelPower = 2.5f;
- float fresnelMultiplier = 0.8f;
- float fresnelHardness = 1.f;
- float fresnel = pow(1.f - max(abs(dot(N, V)), 0), fresnelPower) * fresnelMultiplier;
- vec3 fresnelMask = pow(1.f - max(vec3(0.0f, -1.0f, 0.0f) * N, 0.f), vec3(fresnelHardness));
- return fresnel * fresnelMask * C;
- }
- void main()
- {
- // BASE COLOR
- vec4 color = texture(samplerColorMap, fs_in.texcoord);
- if (ALPHA_MASK)
- if (color.a < ALPHA_MASK_CUTOFF) discard;
- // SAMPLE NORMAL
- vec3 N = texture(samplerNormalMap, fs_in.texcoord).rgb;
- N = normalize(fs_in.TBN * (N * 2.f - 1.f));
- // VECTORS
- vec3 V = normalize(ubo.viewInverse[3].xyz - fs_in.fragPos);
- vec3 R = reflect(V, N);
- // GLOBAL LIGHT
- vec3 ambient = ubo.ambientLighting.xyz * ubo.ambientLighting.w;
- vec3 diffuse = calculate_diffuse(N, ubo.globalLightDirection.xyz, color.rgb * ubo.globalLightDirection.w);
- vec3 specular = calculate_specular(N, V, ubo.globalLightDirection.xyz, vec3(1,1,1) * ubo.globalLightDirection.w);
- vec3 occlusion = texture(samplerOcclusionMap, fs_in.texcoord).rgb;
- // POINT LIGHTS
- for(int i = 0; i < ubo.numLights; i++)
- {
- PointLight light = ubo.pointLights[i];
- vec3 directionToLight = light.position.xyz - fs_in.fragPos;
- float attenuation = 1.f / dot(directionToLight, directionToLight);
- vec3 lightColor = light.color.xyz * color.rgb * light.color.w * attenuation;
- diffuse += calculate_diffuse(N, directionToLight, lightColor);
- specular += calculate_specular(N, V, directionToLight, lightColor);
- }
- // ROUGHNESS
- float roughness = texture(samplerMetallicRoughness, fs_in.texcoord).b;
- specular *= roughness;
- // ENVIRONMENT MAPPING
- vec3 environment = texture(samplerCubeMap, R).rgb;
- environment = calculate_fresnel(N, V, environment) * roughness;
- outFragColor = vec4((ambient + diffuse + specular + environment) * occlusion, color.a);
- }
|