forward.fs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #version 330 core
  2. out vec4 color;
  3. in vec3 frag;
  4. in vec3 normal;
  5. in vec2 uv;
  6. in mat3 TBN;
  7. uniform sampler2D u_texture;
  8. uniform sampler2D u_spec;
  9. uniform sampler2D u_norm;
  10. uniform mat4 u_projection;
  11. uniform mat4 u_view;
  12. uniform mat4 u_inverse_view;
  13. uniform bool u_ambient_pass;
  14. uniform samplerCube u_reflection;
  15. /* spot lights */
  16. const int MAX_SL = 32;
  17. struct spot_light {
  18. vec3 position;
  19. vec3 direction;
  20. vec3 color;
  21. float inner;
  22. float outer;
  23. bool is_shadow;
  24. float far;
  25. };
  26. // for dynamic spotlights
  27. uniform spot_light u_spot_light;
  28. uniform sampler2D u_spot_depth;
  29. // for static spotlights
  30. uniform spot_light u_spot_lights[MAX_SL];
  31. uniform int u_spot_count;
  32. uniform bool u_spot_active;
  33. /* ------------ */
  34. /* dir light */
  35. struct dir_light {
  36. vec3 position;
  37. vec3 target;
  38. vec3 color;
  39. float far;
  40. };
  41. uniform dir_light u_dir_light;
  42. uniform sampler2D u_dir_depth;
  43. uniform mat4 u_dir_transform;
  44. uniform bool u_dir_active;
  45. /* ------------ */
  46. /* point light */
  47. const int MAX_PL = 64;
  48. struct point_light {
  49. vec3 position;
  50. vec3 color;
  51. bool is_shadow;
  52. float far;
  53. };
  54. // for dynamic lights
  55. uniform point_light u_point_light;
  56. uniform samplerCube u_point_depth;
  57. // for static ones done in a single render pass
  58. uniform point_light u_point_lights[MAX_PL];
  59. uniform int u_point_count;
  60. uniform bool u_point_active;
  61. /* ------------ */
  62. vec3 pcf_offset[20] = vec3[]
  63. (
  64. vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
  65. vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
  66. vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
  67. vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
  68. vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
  69. );
  70. vec3 calc_point_light(point_light light)
  71. {
  72. point_light l = light;
  73. l.position = vec3(u_view * vec4(l.position, 1.0));
  74. vec3 fragpos = frag;
  75. vec3 normals = texture(u_norm, uv).rgb;
  76. normals = normalize(normals * 2.0 - 1.0);
  77. normals = normalize(TBN * normals);
  78. vec3 diff = texture(u_texture, uv).rgb;
  79. vec3 spec = texture(u_spec, uv).rgb;
  80. vec3 view_dir = normalize(-fragpos);
  81. vec3 light_dir = l.position - fragpos;
  82. float dist = length(light_dir);
  83. light_dir = normalize(light_dir);
  84. // diffuse
  85. vec3 diffuse = max(dot(light_dir, normals), 0.0) * diff * l.color;
  86. // specular
  87. vec3 halfwayd = normalize(light_dir + view_dir);
  88. float specs = pow(max(dot(normals, halfwayd), 0.0), 64.0f);
  89. vec3 specular = l.color * specs * spec;
  90. // attenuation
  91. float attenuation = 1.0f / (1.0f + 0.14f * dist + 0.07f * (dist * dist));
  92. diffuse *= attenuation;
  93. specular *= attenuation;
  94. // shadows
  95. float costheta = clamp(dot(normals, light_dir), 0.0, 1.0);
  96. float bias = 0.2*tan(acos(costheta));
  97. bias = clamp(bias, 0.1, 0.2);
  98. float shadow = 0.0f;
  99. if (l.is_shadow) {
  100. vec3 frag_to_light = mat3(u_inverse_view) * (fragpos - l.position);
  101. float current_depth = length(frag_to_light);
  102. float view_dist = length(-fragpos);
  103. // PCF smoothing
  104. float radius = (1.0 + (view_dist / l.far)) / l.far;
  105. float offset = 0.1;
  106. int samples = 20;
  107. float closest_depth = 0.0f;
  108. for (int i=0; i<samples; ++i) {
  109. closest_depth = texture(u_point_depth, frag_to_light + pcf_offset[i] * radius).r;
  110. closest_depth *= l.far;
  111. if (current_depth - bias > closest_depth)
  112. shadow += 1.0;
  113. }
  114. shadow /= float(samples);
  115. }
  116. return vec3((1.0 - shadow) * (diffuse + specular));
  117. }
  118. vec3 aces_tonemap(vec3 x) {
  119. float a = 2.51;
  120. float b = 0.03;
  121. float c = 2.43;
  122. float d = 0.59;
  123. float e = 0.14;
  124. return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
  125. }
  126. void main()
  127. {
  128. vec3 diffuse = vec3(0.0f);
  129. if (u_ambient_pass) {
  130. diffuse += texture(u_texture, uv).rgb * 0.06;
  131. } else {
  132. // shadow casters
  133. if (u_point_active && u_point_count <= 0)
  134. diffuse += calc_point_light(u_point_light);
  135. }
  136. // non shadow casters
  137. if (u_point_count > 0)
  138. for (int i=0; i<u_point_count; i++)
  139. diffuse += calc_point_light(u_point_lights[i]);
  140. vec3 tex_color = vec3(1.0) - exp(-diffuse * 1.0);
  141. color = vec4(aces_tonemap(tex_color), 2.5);
  142. }