fog.glslf 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #ifndef FOG_GLSLF
  2. #define FOG_GLSLF
  3. // #import u_cube_fog u_fog_color_density u_underwater_fog_color_density
  4. // #import u_cam_water_depth u_fog_params
  5. // #import v_pos_world
  6. /*==============================================================================
  7. VARS
  8. ==============================================================================*/
  9. #var USE_FOG 0
  10. #var WATER_EFFECTS 0
  11. #var FOG_TYPE QUADRATIC
  12. #var PROCEDURAL_FOG 0
  13. /*============================================================================*/
  14. #include <std.glsl>
  15. #include <color_util.glslf>
  16. #if USE_FOG
  17. void shade_fog(inout vec3 color, in float eye_dist, in float height,
  18. in vec4 fog_color_density)
  19. {
  20. float fac = clamp((eye_dist - u_fog_params.z) / u_fog_params.y , 0.0, 1.0);
  21. # if FOG_TYPE == QUADRATIC
  22. fac *= fac;
  23. # elif FOG_TYPE == LINEAR
  24. /* pass */
  25. # elif FOG_TYPE == INVERSE_QUADRATIC
  26. fac = sqrt(fac);
  27. # endif
  28. if (u_fog_params.w > 0.0) {
  29. if (height > u_fog_params.w)
  30. fac = 0.0;
  31. else {
  32. float hi = (u_fog_params.w - max(height, 0.0)) / u_fog_params.w;
  33. fac *= hi * hi;
  34. }
  35. }
  36. fog_color_density.a = 1.0 - (1.0 - fac) * (1.0 - u_fog_params.x);
  37. color = mix(color, fog_color_density.rgb, fog_color_density.a);
  38. }
  39. #endif
  40. #if PROCEDURAL_FOG
  41. vec3 procedural_fog_color(in mat4 cube_fog, in vec3 eye_dir)
  42. {
  43. vec3 x_fog = mix( cube_fog[0].rgb, cube_fog[1].rgb,
  44. max(sign(eye_dir.x), 0.0) );
  45. vec3 z_fog = mix( cube_fog[2].rgb, cube_fog[3].rgb,
  46. max(sign(eye_dir.z), 0.0) );
  47. vec3 y_fog = vec3(cube_fog[0].a, cube_fog[1].a, cube_fog[2].a);
  48. vec3 color = mix(x_fog, z_fog, abs(eye_dir.z));
  49. color = mix(color, y_fog, abs(eye_dir.y));
  50. srgb_to_lin(color);
  51. return color;
  52. }
  53. #endif
  54. #if WATER_EFFECTS
  55. void water_fog_factor(inout float f)
  56. {
  57. /*
  58. ^ Visibility
  59. _|
  60. 1 |*
  61. |*
  62. | *
  63. | **
  64. _| ***
  65. 0.5| **
  66. | *
  67. | *
  68. | *
  69. ---|------------------->
  70. Distance
  71. */
  72. f -= 0.5;
  73. f = 4.0 * (f * f * f) + 0.5;
  74. }
  75. void fog_underwater(inout vec3 color, in float eye_dist,
  76. in vec3 eye_dir, in float cam_depth, in vec4 underwater_fog_color_density,
  77. in float dist_to_water_level)
  78. {
  79. float eye_dir_z = max(eye_dir.z, 0.0);
  80. float eye_fac = max(eye_dist - max(cam_depth / eye_dir_z, 0.0), 0.0);
  81. float water_fac = underwater_fog_color_density.w * eye_fac;
  82. vec3 depth_col = vec3(0.0, 0.02, 0.05);
  83. vec3 water_col = underwater_fog_color_density.rgb;
  84. // vertical gradient to smooth fog artifacts for dynamic water
  85. water_fac = min(water_fac, 1.0);
  86. water_fog_factor(water_fac);
  87. water_fac *= clamp(2.0 - dist_to_water_level, 0.0, 1.0);
  88. vec3 fog_color = mix(water_col, depth_col, min(eye_dir_z, 1.0));
  89. cam_depth = clamp(-cam_depth * 0.03, 0.0, 0.8);
  90. fog_color *= 1.0 - cam_depth;
  91. color = mix(color, fog_color, water_fac);
  92. }
  93. #endif
  94. void fog(inout vec3 color, float eye_dist, vec3 eye_dir, float dist_to_water)
  95. {
  96. #if USE_FOG
  97. # if PROCEDURAL_FOG
  98. vec3 cube_fog = procedural_fog_color(u_cube_fog, eye_dir);
  99. vec4 fog_color = vec4(cube_fog, u_fog_color_density.a);
  100. # else // PROCEDURAL_FOG
  101. vec4 fog_color = u_fog_color_density;
  102. # endif // PROCEDURAL_FOG
  103. shade_fog(color, eye_dist, v_pos_world.z, fog_color);
  104. #endif
  105. #if WATER_EFFECTS
  106. fog_underwater(color, eye_dist, eye_dir, u_cam_water_depth,
  107. u_underwater_fog_color_density, dist_to_water);
  108. #endif
  109. }
  110. #endif