sky.glsl 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* clang-format off */
  2. #[modes]
  3. mode_background =
  4. mode_cubemap = #define USE_CUBEMAP_PASS
  5. #[specializations]
  6. USE_MULTIVIEW = false
  7. USE_INVERTED_Y = true
  8. APPLY_TONEMAPPING = true
  9. USE_QUARTER_RES_PASS = false
  10. USE_HALF_RES_PASS = false
  11. #[vertex]
  12. layout(location = 0) in vec2 vertex_attrib;
  13. out vec2 uv_interp;
  14. /* clang-format on */
  15. void main() {
  16. #ifdef USE_INVERTED_Y
  17. uv_interp = vertex_attrib;
  18. #else
  19. // We're doing clockwise culling so flip the order
  20. uv_interp = vec2(vertex_attrib.x, vertex_attrib.y * -1.0);
  21. #endif
  22. gl_Position = vec4(uv_interp, -1.0, 1.0);
  23. }
  24. /* clang-format off */
  25. #[fragment]
  26. #define M_PI 3.14159265359
  27. #include "tonemap_inc.glsl"
  28. in vec2 uv_interp;
  29. /* clang-format on */
  30. uniform samplerCube radiance; //texunit:-1
  31. #ifdef USE_CUBEMAP_PASS
  32. uniform samplerCube half_res; //texunit:-2
  33. uniform samplerCube quarter_res; //texunit:-3
  34. #elif defined(USE_MULTIVIEW)
  35. uniform sampler2DArray half_res; //texunit:-2
  36. uniform sampler2DArray quarter_res; //texunit:-3
  37. #else
  38. uniform sampler2D half_res; //texunit:-2
  39. uniform sampler2D quarter_res; //texunit:-3
  40. #endif
  41. layout(std140) uniform GlobalShaderUniformData { //ubo:1
  42. vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
  43. };
  44. struct DirectionalLightData {
  45. vec4 direction_energy;
  46. vec4 color_size;
  47. bool enabled;
  48. };
  49. layout(std140) uniform DirectionalLights { //ubo:4
  50. DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
  51. }
  52. directional_lights;
  53. /* clang-format off */
  54. #ifdef MATERIAL_UNIFORMS_USED
  55. layout(std140) uniform MaterialUniforms{ //ubo:3
  56. #MATERIAL_UNIFORMS
  57. };
  58. #endif
  59. /* clang-format on */
  60. #GLOBALS
  61. #ifdef USE_CUBEMAP_PASS
  62. #define AT_CUBEMAP_PASS true
  63. #else
  64. #define AT_CUBEMAP_PASS false
  65. #endif
  66. #ifdef USE_HALF_RES_PASS
  67. #define AT_HALF_RES_PASS true
  68. #else
  69. #define AT_HALF_RES_PASS false
  70. #endif
  71. #ifdef USE_QUARTER_RES_PASS
  72. #define AT_QUARTER_RES_PASS true
  73. #else
  74. #define AT_QUARTER_RES_PASS false
  75. #endif
  76. // mat4 is a waste of space, but we don't have an easy way to set a mat3 uniform for now
  77. uniform mat4 orientation;
  78. uniform vec4 projection;
  79. uniform vec3 position;
  80. uniform float time;
  81. uniform float sky_energy_multiplier;
  82. uniform float luminance_multiplier;
  83. uniform float fog_aerial_perspective;
  84. uniform vec4 fog_light_color;
  85. uniform float fog_sun_scatter;
  86. uniform bool fog_enabled;
  87. uniform float fog_density;
  88. uniform float fog_sky_affect;
  89. uniform uint directional_light_count;
  90. #ifdef USE_MULTIVIEW
  91. layout(std140) uniform MultiviewData { // ubo:11
  92. highp mat4 projection_matrix_view[MAX_VIEWS];
  93. highp mat4 inv_projection_matrix_view[MAX_VIEWS];
  94. highp vec4 eye_offset[MAX_VIEWS];
  95. }
  96. multiview_data;
  97. #endif
  98. layout(location = 0) out vec4 frag_color;
  99. #ifdef USE_DEBANDING
  100. // https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
  101. vec3 interleaved_gradient_noise(vec2 pos) {
  102. const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);
  103. float res = fract(magic.z * fract(dot(pos, magic.xy))) * 2.0 - 1.0;
  104. return vec3(res, -res, res) / 255.0;
  105. }
  106. #endif
  107. #if !defined(DISABLE_FOG)
  108. vec4 fog_process(vec3 view, vec3 sky_color) {
  109. vec3 fog_color = mix(fog_light_color.rgb, sky_color, fog_aerial_perspective);
  110. if (fog_sun_scatter > 0.001) {
  111. vec4 sun_scatter = vec4(0.0);
  112. float sun_total = 0.0;
  113. for (uint i = 0u; i < directional_light_count; i++) {
  114. vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
  115. float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
  116. fog_color += light_color * light_amount * fog_sun_scatter;
  117. }
  118. }
  119. return vec4(fog_color, 1.0);
  120. }
  121. #endif // !DISABLE_FOG
  122. void main() {
  123. vec3 cube_normal;
  124. #ifdef USE_MULTIVIEW
  125. // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
  126. vec4 unproject = vec4(uv_interp.xy, -1.0, 1.0); // unproject at the far plane
  127. vec4 unprojected = multiview_data.inv_projection_matrix_view[ViewIndex] * unproject;
  128. cube_normal = unprojected.xyz / unprojected.w;
  129. // Unproject will give us the position between the eyes, need to re-offset.
  130. cube_normal += multiview_data.eye_offset[ViewIndex].xyz;
  131. #else
  132. cube_normal.z = -1.0;
  133. cube_normal.x = (uv_interp.x + projection.x) / projection.y;
  134. cube_normal.y = (-uv_interp.y - projection.z) / projection.w;
  135. #endif
  136. cube_normal = mat3(orientation) * cube_normal;
  137. cube_normal = normalize(cube_normal);
  138. vec2 uv = gl_FragCoord.xy; // uv_interp * 0.5 + 0.5;
  139. vec2 panorama_coords = vec2(atan(cube_normal.x, -cube_normal.z), acos(cube_normal.y));
  140. if (panorama_coords.x < 0.0) {
  141. panorama_coords.x += M_PI * 2.0;
  142. }
  143. panorama_coords /= vec2(M_PI * 2.0, M_PI);
  144. vec3 color = vec3(0.0, 0.0, 0.0);
  145. float alpha = 1.0; // Only available to subpasses
  146. vec4 half_res_color = vec4(1.0);
  147. vec4 quarter_res_color = vec4(1.0);
  148. vec4 custom_fog = vec4(0.0);
  149. #ifdef USE_CUBEMAP_PASS
  150. #ifdef USES_HALF_RES_COLOR
  151. half_res_color = texture(samplerCube(half_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), cube_normal);
  152. #endif
  153. #ifdef USES_QUARTER_RES_COLOR
  154. quarter_res_color = texture(samplerCube(quarter_res, SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), cube_normal);
  155. #endif
  156. #else
  157. #ifdef USES_HALF_RES_COLOR
  158. #ifdef USE_MULTIVIEW
  159. half_res_color = textureLod(sampler2DArray(half_res, SAMPLER_LINEAR_CLAMP), vec3(uv, ViewIndex), 0.0);
  160. #else
  161. half_res_color = textureLod(sampler2D(half_res, SAMPLER_LINEAR_CLAMP), uv, 0.0);
  162. #endif
  163. #endif
  164. #ifdef USES_QUARTER_RES_COLOR
  165. #ifdef USE_MULTIVIEW
  166. quarter_res_color = textureLod(sampler2DArray(quarter_res, SAMPLER_LINEAR_CLAMP), vec3(uv, ViewIndex), 0.0);
  167. #else
  168. quarter_res_color = textureLod(sampler2D(quarter_res, SAMPLER_LINEAR_CLAMP), uv, 0.0);
  169. #endif
  170. #endif
  171. #endif
  172. {
  173. #CODE : SKY
  174. }
  175. color *= sky_energy_multiplier;
  176. // Convert to Linear for tonemapping so color matches scene shader better
  177. color = srgb_to_linear(color);
  178. #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
  179. // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
  180. if (fog_enabled) {
  181. vec4 fog = fog_process(cube_normal, color.rgb);
  182. color.rgb = mix(color.rgb, fog.rgb, fog.a * fog_sky_affect);
  183. }
  184. if (custom_fog.a > 0.0) {
  185. color.rgb = mix(color.rgb, custom_fog.rgb, custom_fog.a);
  186. }
  187. #endif // DISABLE_FOG
  188. color *= exposure;
  189. #ifdef APPLY_TONEMAPPING
  190. color = apply_tonemapping(color, white);
  191. #endif
  192. color = linear_to_srgb(color);
  193. frag_color.rgb = color * luminance_multiplier;
  194. frag_color.a = alpha;
  195. #ifdef USE_DEBANDING
  196. frag_color.rgb += interleaved_gradient_noise(gl_FragCoord.xy) * sky_energy_multiplier * luminance_multiplier;
  197. #endif
  198. }