simple_shader.frag 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #version 450
  2. struct PointLight
  3. {
  4. vec4 position; // w is radius
  5. vec4 color; // w is intensity
  6. };
  7. layout (set = 0, binding = 0) uniform GlobalUBO
  8. {
  9. // MATRICES
  10. mat4 view;
  11. mat4 viewInverse;
  12. mat4 viewProjection;
  13. // LIGHTING
  14. vec4 globalLightDirection;
  15. vec4 ambientLighting;
  16. // POINT LIGHTS
  17. PointLight pointLights[8];
  18. int numLights;
  19. } ubo;
  20. // SAMPLERS
  21. layout (set = 0, binding = 1) uniform samplerCube samplerCubeMap;
  22. layout (set = 1, binding = 0) uniform sampler2D samplerColorMap;
  23. layout (set = 1, binding = 1) uniform sampler2D samplerNormalMap;
  24. layout (set = 1, binding = 2) uniform sampler2D samplerOcclusionMap;
  25. layout (set = 1, binding = 3) uniform sampler2D samplerMetallicRoughness;
  26. // CONSTANTS
  27. layout (constant_id = 0) const bool ALPHA_MASK = false;
  28. layout (constant_id = 1) const float ALPHA_MASK_CUTOFF = 0.0f;
  29. // FRAGMENT INPUT
  30. layout (location = 0) in struct FS_IN
  31. {
  32. vec3 fragPos;
  33. vec2 texcoord;
  34. mat3 TBN;
  35. } fs_in;
  36. // OUT COLOR
  37. layout (location = 0) out vec4 outFragColor;
  38. vec3 calculate_diffuse(vec3 N, vec3 L, vec3 C)
  39. {
  40. float diffuse_strength = max(dot(N, L), 0);
  41. // HALF-LAMBERT
  42. diffuse_strength = pow(diffuse_strength * 0.5f + 0.5f, 2);
  43. diffuse_strength = max(diffuse_strength, 0.f);
  44. return C * diffuse_strength;
  45. }
  46. vec3 calculate_specular(vec3 N, vec3 V, vec3 L, vec3 C)
  47. {
  48. V = normalize(V);
  49. L = normalize(L);
  50. // HALF VECTOR
  51. vec3 halfVector = normalize(L + V);
  52. // Specularity
  53. float shininess = 16.f;
  54. float specularity = pow(max(dot(N, halfVector), 0.f), shininess * shininess);
  55. return C * specularity;
  56. }
  57. vec3 calculate_fresnel(vec3 N, vec3 V, vec3 C)
  58. {
  59. float fresnelPower = 2.5f;
  60. float fresnelMultiplier = 0.8f;
  61. float fresnelHardness = 1.f;
  62. float fresnel = pow(1.f - max(abs(dot(N, V)), 0), fresnelPower) * fresnelMultiplier;
  63. vec3 fresnelMask = pow(1.f - max(vec3(0.0f, -1.0f, 0.0f) * N, 0.f), vec3(fresnelHardness));
  64. return fresnel * fresnelMask * C;
  65. }
  66. void main()
  67. {
  68. // BASE COLOR
  69. vec4 color = texture(samplerColorMap, fs_in.texcoord);
  70. if (ALPHA_MASK)
  71. if (color.a < ALPHA_MASK_CUTOFF) discard;
  72. // SAMPLE NORMAL
  73. vec3 N = texture(samplerNormalMap, fs_in.texcoord).rgb;
  74. N = normalize(fs_in.TBN * (N * 2.f - 1.f));
  75. // VECTORS
  76. vec3 V = normalize(ubo.viewInverse[3].xyz - fs_in.fragPos);
  77. vec3 R = reflect(V, N);
  78. // GLOBAL LIGHT
  79. vec3 ambient = ubo.ambientLighting.xyz * ubo.ambientLighting.w;
  80. vec3 diffuse = calculate_diffuse(N, ubo.globalLightDirection.xyz, color.rgb * ubo.globalLightDirection.w);
  81. vec3 specular = calculate_specular(N, V, ubo.globalLightDirection.xyz, vec3(1,1,1) * ubo.globalLightDirection.w);
  82. vec3 occlusion = texture(samplerOcclusionMap, fs_in.texcoord).rgb;
  83. // POINT LIGHTS
  84. for(int i = 0; i < ubo.numLights; i++)
  85. {
  86. PointLight light = ubo.pointLights[i];
  87. vec3 directionToLight = light.position.xyz - fs_in.fragPos;
  88. float attenuation = 1.f / dot(directionToLight, directionToLight);
  89. vec3 lightColor = light.color.xyz * color.rgb * light.color.w * attenuation;
  90. diffuse += calculate_diffuse(N, directionToLight, lightColor);
  91. specular += calculate_specular(N, V, directionToLight, lightColor);
  92. }
  93. // ROUGHNESS
  94. float roughness = texture(samplerMetallicRoughness, fs_in.texcoord).b;
  95. specular *= roughness;
  96. // ENVIRONMENT MAPPING
  97. vec3 environment = texture(samplerCubeMap, R).rgb;
  98. environment = calculate_fresnel(N, V, environment) * roughness;
  99. outFragColor = vec4((ambient + diffuse + specular + environment) * occlusion, color.a);
  100. }