proc_skybox.glslf 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #version GLSL_VERSION
  2. #include <precision_statement.glslf>
  3. #include <std.glsl>
  4. #include <color_util.glslf>
  5. uniform vec3 u_sky_color;
  6. uniform vec3 u_sun_direction;
  7. uniform float u_rayleigh_brightness;
  8. uniform float u_mie_brightness;
  9. uniform float u_spot_brightness;
  10. uniform float u_scatter_strength;
  11. uniform float u_rayleigh_strength;
  12. uniform float u_mie_strength;
  13. uniform float u_rayleigh_collection_power;
  14. uniform float u_mie_collection_power;
  15. uniform float u_mie_distribution;
  16. //vec3 Kr = vec3(0.18867780436772762, 0.4978442963618773, 0.6616065586417131); // air
  17. /*==============================================================================
  18. SHADER INTERFACE
  19. ==============================================================================*/
  20. GLSL_IN vec3 v_ray;
  21. //------------------------------------------------------------------------------
  22. GLSL_OUT vec4 GLSL_OUT_FRAG_COLOR;
  23. /*============================================================================*/
  24. const float surface_height = 0.99;
  25. const float intensity = 1.8;
  26. const int step_count = 8;
  27. float atmospheric_depth(vec3 position, vec3 dir) {
  28. float a = dot(dir, dir);
  29. float b = 2.0*dot(dir, position);
  30. float c = dot(position, position)-1.0;
  31. float det = b*b-4.0*a*c;
  32. float detSqrt = sqrt(det);
  33. float q = (-b - detSqrt)/2.0;
  34. float t1 = c/q;
  35. return t1;
  36. }
  37. float phase(float alpha, float g) {
  38. float a = 3.0*(1.0-g*g);
  39. float b = 2.0*(2.0+g*g);
  40. float c = 1.0+alpha*alpha;
  41. float d = pow(1.0+g*g-2.0*g*alpha, 1.5);
  42. d = max(d, 0.00001);
  43. return (a/b)*(c/d);
  44. }
  45. float horizon_extinction(vec3 position, vec3 dir, float radius) {
  46. float u = dot(dir, -position);
  47. if(u<0.0){
  48. return 1.0;
  49. }
  50. vec3 near = position + u*dir;
  51. if(length(near) < radius){
  52. return 0.0;
  53. }
  54. else if (length(near) >= radius){
  55. vec3 v2 = normalize(near)*radius - position;
  56. float diff = acos(dot(normalize(v2), dir));
  57. return smoothstep(0.0, 1.0, pow(diff*2.0, 3.0));
  58. }
  59. else
  60. return 1.0;
  61. }
  62. vec3 absorb(float dist, vec3 color, float factor){
  63. return color-color*pow(u_sky_color, vec3(factor/dist));
  64. }
  65. /*==============================================================================
  66. MAIN
  67. ==============================================================================*/
  68. void main(void) {
  69. vec3 ray = normalize(v_ray);
  70. vec3 ldir = u_sun_direction;
  71. float alpha = dot(ray, ldir);
  72. float rayleigh_factor = phase(alpha, -0.01) * u_rayleigh_brightness * ldir.z;
  73. float mie_factor = phase(alpha - 0.5, u_mie_distribution) * u_mie_brightness
  74. * (1.0 - ldir.z);
  75. float spot = smoothstep(0.0, 100.0, phase(alpha, 0.9995)) * u_spot_brightness;
  76. vec3 eye_position = vec3(0.0, 0.0, surface_height);
  77. float eye_depth = atmospheric_depth(eye_position, ray);
  78. float step_length = eye_depth/float(step_count);
  79. float eye_extinction = horizon_extinction(eye_position, ray,
  80. surface_height - 0.3);
  81. vec3 rayleigh_collected = vec3(0.0, 0.0, 0.0);
  82. vec3 mie_collected = vec3(0.0, 0.0, 0.0);
  83. for(int i=0; i < step_count; i++) {
  84. float sample_distance = step_length * float(i);
  85. vec3 position = eye_position + ray * sample_distance;
  86. float extinction = horizon_extinction(position,
  87. ldir,
  88. surface_height - 0.2
  89. );
  90. float sample_depth = atmospheric_depth(position, ldir);
  91. vec3 influx = absorb(sample_depth, vec3(intensity), u_scatter_strength)
  92. * extinction;
  93. rayleigh_collected += absorb(sqrt(sample_distance), u_sky_color * influx,
  94. u_rayleigh_strength);
  95. mie_collected += absorb(sample_distance, influx, u_mie_strength);
  96. }
  97. rayleigh_collected = rayleigh_collected * eye_extinction
  98. * pow(eye_depth, u_rayleigh_collection_power)
  99. / float(step_count);
  100. mie_collected = (mie_collected * eye_extinction
  101. * pow(eye_depth, u_mie_collection_power))
  102. / float(step_count);
  103. vec3 color = vec3(spot * mie_collected
  104. + mie_factor * mie_collected
  105. + rayleigh_factor * rayleigh_collected);
  106. lin_to_srgb(color);
  107. GLSL_OUT_FRAG_COLOR = vec4(color, 1.0);
  108. }