No Description

scene.frag 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #version 450
  2. #define SHADOW_MAP_CASCADE_COUNT 4
  3. layout (set = 0, binding = 1) uniform sampler2DArray shadowMap;
  4. layout (set = 1, binding = 0) uniform sampler2D colorMap;
  5. layout (location = 0) in vec3 inNormal;
  6. layout (location = 1) in vec3 inColor;
  7. layout (location = 2) in vec3 inViewPos;
  8. layout (location = 3) in vec3 inPos;
  9. layout (location = 4) in vec2 inUV;
  10. layout (constant_id = 0) const int enablePCF = 0;
  11. layout (location = 0) out vec4 outFragColor;
  12. #define ambient 0.3
  13. layout (set = 0, binding = 2) uniform UBO {
  14. vec4 cascadeSplits;
  15. mat4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT];
  16. mat4 inverseViewMat;
  17. vec3 lightDir;
  18. float _pad;
  19. int colorCascades;
  20. } ubo;
  21. const mat4 biasMat = mat4(
  22. 0.5, 0.0, 0.0, 0.0,
  23. 0.0, 0.5, 0.0, 0.0,
  24. 0.0, 0.0, 1.0, 0.0,
  25. 0.5, 0.5, 0.0, 1.0
  26. );
  27. float textureProj(vec4 P, vec2 offset, uint cascadeIndex)
  28. {
  29. float shadow = 1.0;
  30. float bias = 0.005;
  31. vec4 shadowCoord = P / P.w;
  32. if ( shadowCoord.z > -1.0 && shadowCoord.z < 1.0 ) {
  33. float dist = texture(shadowMap, vec3(shadowCoord.st + offset, cascadeIndex)).r;
  34. if (shadowCoord.w > 0 && dist < shadowCoord.z - bias) {
  35. shadow = ambient;
  36. }
  37. }
  38. return shadow;
  39. }
  40. float filterPCF(vec4 sc, uint cascadeIndex)
  41. {
  42. ivec2 texDim = textureSize(shadowMap, 0).xy;
  43. float scale = 0.75;
  44. float dx = scale * 1.0 / float(texDim.x);
  45. float dy = scale * 1.0 / float(texDim.y);
  46. float shadowFactor = 0.0;
  47. int count = 0;
  48. int range = 1;
  49. for (int x = -range; x <= range; x++) {
  50. for (int y = -range; y <= range; y++) {
  51. shadowFactor += textureProj(sc, vec2(dx*x, dy*y), cascadeIndex);
  52. count++;
  53. }
  54. }
  55. return shadowFactor / count;
  56. }
  57. void main()
  58. {
  59. vec4 color = texture(colorMap, inUV);
  60. if (color.a < 0.5) {
  61. discard;
  62. }
  63. // Get cascade index for the current fragment's view position
  64. uint cascadeIndex = 0;
  65. for(uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) {
  66. if(inViewPos.z < ubo.cascadeSplits[i]) {
  67. cascadeIndex = i + 1;
  68. }
  69. }
  70. // Depth compare for shadowing
  71. vec4 shadowCoord = (biasMat * ubo.cascadeViewProjMat[cascadeIndex]) * vec4(inPos, 1.0);
  72. float shadow = 0;
  73. if (enablePCF == 1) {
  74. shadow = filterPCF(shadowCoord / shadowCoord.w, cascadeIndex);
  75. } else {
  76. shadow = textureProj(shadowCoord / shadowCoord.w, vec2(0.0), cascadeIndex);
  77. }
  78. // Directional light
  79. vec3 N = normalize(inNormal);
  80. vec3 L = normalize(-ubo.lightDir);
  81. vec3 H = normalize(L + inViewPos);
  82. float diffuse = max(dot(N, L), ambient);
  83. vec3 lightColor = vec3(1.0);
  84. outFragColor.rgb = max(lightColor * (diffuse * color.rgb), vec3(0.0));
  85. outFragColor.rgb *= shadow;
  86. outFragColor.a = color.a;
  87. // Color cascades (if enabled)
  88. if (ubo.colorCascades == 1) {
  89. switch(cascadeIndex) {
  90. case 0 :
  91. outFragColor.rgb *= vec3(1.0f, 0.25f, 0.25f);
  92. break;
  93. case 1 :
  94. outFragColor.rgb *= vec3(0.25f, 1.0f, 0.25f);
  95. break;
  96. case 2 :
  97. outFragColor.rgb *= vec3(0.25f, 0.25f, 1.0f);
  98. break;
  99. case 3 :
  100. outFragColor.rgb *= vec3(1.0f, 1.0f, 0.25f);
  101. break;
  102. }
  103. }
  104. }