Ei kuvausta

deferred.frag 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #version 450
  2. #extension GL_ARB_separate_shader_objects : enable
  3. #extension GL_ARB_shading_language_420pack : enable
  4. layout (binding = 1) uniform sampler2D samplerposition;
  5. layout (binding = 2) uniform sampler2D samplerNormal;
  6. layout (binding = 3) uniform sampler2D samplerAlbedo;
  7. // Depth from the light's point of view
  8. //layout (binding = 5) uniform sampler2DShadow samplerShadowMap;
  9. layout (binding = 5) uniform sampler2DArray samplerShadowMap;
  10. layout (location = 0) in vec2 inUV;
  11. layout (location = 0) out vec4 outFragColor;
  12. #define LIGHT_COUNT 3
  13. #define SHADOW_FACTOR 0.25
  14. #define AMBIENT_LIGHT 0.1
  15. #define USE_PCF
  16. struct Light
  17. {
  18. vec4 position;
  19. vec4 target;
  20. vec4 color;
  21. mat4 viewMatrix;
  22. };
  23. layout (binding = 4) uniform UBO
  24. {
  25. vec4 viewPos;
  26. Light lights[LIGHT_COUNT];
  27. int useShadows;
  28. } ubo;
  29. float textureProj(vec4 P, float layer, vec2 offset)
  30. {
  31. float shadow = 1.0;
  32. vec4 shadowCoord = P / P.w;
  33. shadowCoord.st = shadowCoord.st * 0.5 + 0.5;
  34. if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0)
  35. {
  36. float dist = texture(samplerShadowMap, vec3(shadowCoord.st + offset, layer)).r;
  37. if (shadowCoord.w > 0.0 && dist < shadowCoord.z)
  38. {
  39. shadow = SHADOW_FACTOR;
  40. }
  41. }
  42. return shadow;
  43. }
  44. float filterPCF(vec4 sc, float layer)
  45. {
  46. ivec2 texDim = textureSize(samplerShadowMap, 0).xy;
  47. float scale = 1.5;
  48. float dx = scale * 1.0 / float(texDim.x);
  49. float dy = scale * 1.0 / float(texDim.y);
  50. float shadowFactor = 0.0;
  51. int count = 0;
  52. int range = 1;
  53. for (int x = -range; x <= range; x++)
  54. {
  55. for (int y = -range; y <= range; y++)
  56. {
  57. shadowFactor += textureProj(sc, layer, vec2(dx*x, dy*y));
  58. count++;
  59. }
  60. }
  61. return shadowFactor / count;
  62. }
  63. void main()
  64. {
  65. // Get G-Buffer values
  66. vec3 fragPos = texture(samplerposition, inUV).rgb;
  67. vec3 normal = texture(samplerNormal, inUV).rgb;
  68. vec4 albedo = texture(samplerAlbedo, inUV);
  69. // Ambient part
  70. vec3 fragcolor = albedo.rgb * AMBIENT_LIGHT;
  71. vec3 N = normalize(normal);
  72. float shadow = 0.0;
  73. for(int i = 0; i < LIGHT_COUNT; ++i)
  74. {
  75. // Vector to light
  76. vec3 L = ubo.lights[i].position.xyz - fragPos;
  77. // Distance from light to fragment position
  78. float dist = length(L);
  79. L = normalize(L);
  80. // Viewer to fragment
  81. vec3 V = ubo.viewPos.xyz - fragPos;
  82. V = normalize(V);
  83. float lightCosInnerAngle = cos(radians(15.0));
  84. float lightCosOuterAngle = cos(radians(25.0));
  85. float lightRange = 100.0;
  86. // Direction vector from source to target
  87. vec3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz);
  88. // Dual cone spot light with smooth transition between inner and outer angle
  89. float cosDir = dot(L, dir);
  90. float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir);
  91. float heightAttenuation = smoothstep(lightRange, 0.0f, dist);
  92. // Diffuse lighting
  93. float NdotL = max(0.0, dot(N, L));
  94. vec3 diff = vec3(NdotL);
  95. // Specular lighting
  96. vec3 R = reflect(-L, N);
  97. float NdotR = max(0.0, dot(R, V));
  98. vec3 spec = vec3(pow(NdotR, 16.0) * albedo.a * 2.5);
  99. fragcolor += vec3((diff + spec) * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb * albedo.rgb;
  100. }
  101. // Shadow calculations in a separate pass
  102. if (ubo.useShadows > 0)
  103. {
  104. for(int i = 0; i < LIGHT_COUNT; ++i)
  105. {
  106. vec4 shadowClip = ubo.lights[i].viewMatrix * vec4(fragPos, 1.0);
  107. float shadowFactor;
  108. #ifdef USE_PCF
  109. shadowFactor= filterPCF(shadowClip, i);
  110. #else
  111. shadowFactor = textureProj(shadowClip, i, vec2(0.0));
  112. #endif
  113. fragcolor *= shadowFactor;
  114. }
  115. }
  116. outFragColor.rgb = fragcolor;
  117. }