Advertisement
Guest User

Untitled

a guest
Jan 14th, 2025
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.64 KB | Source Code | 0 0
  1. #version 450
  2.  
  3. layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
  4.  
  5. #define PI 3.14159
  6.  
  7. struct particle
  8. {
  9.     vec2 pos;
  10.     float height;
  11.     float angle;
  12.     float tilt;
  13.     float vel;
  14.     float opacity;
  15.     float temp;
  16. };
  17.  
  18. struct draw_indirect_cmd
  19. {
  20.     uint vertex_count;
  21.     uint instance_count;
  22.     uint first_vertex;
  23.     uint first_instance;
  24. };
  25.  
  26. layout (binding = 0) uniform frustum_info
  27. {
  28.     vec4 planes[6];
  29. }   frustum;
  30.  
  31. layout (std140, binding = 1) buffer stars
  32. {
  33.     particle particles[];
  34. }   particles;
  35.  
  36. layout (std140, binding = 2) writeonly buffer indirect_draws
  37. {
  38.     draw_indirect_cmd draws[];
  39. }   draws;
  40.  
  41. layout (binding = 3) buffer count_buffer
  42. {
  43.     uint draw_count;
  44. }   count;
  45.  
  46. layout (push_constant) uniform galaxy
  47. {
  48.     uint star_count;
  49.     float max_rad, bulge_rad;
  50.     float angle, eccentricity;
  51.     float base_height, height;
  52.     float dust_temp, min_temp, max_temp;
  53.     float min_star_opacity, max_star_opacity, min_dust_opacity, max_dust_opacity;
  54.     float speed;
  55. }   galaxy_params;
  56.  
  57. // http://www.gamedev.net/topic/592001-random-number-generation-based-on-time-in-hlsl/
  58. #define RANDOM_IA 16807
  59. #define RANDOM_IM 2147483647
  60. #define RANDOM_AM 1.0 / float(RANDOM_IM)
  61. #define RANDOM_IQ 127773
  62. #define RANDOM_IR 2836
  63. #define RANDOM_MASK 123459876
  64.  
  65. int _SEED = 0;
  66.  
  67. void srand_cycle(void)
  68. {
  69.     _SEED ^= RANDOM_MASK;
  70.     int k = _SEED / RANDOM_IQ;
  71.     _SEED = RANDOM_IA * (_SEED - k * RANDOM_IQ) - RANDOM_IR * k;
  72.  
  73.     if (_SEED < 0)
  74.         _SEED += RANDOM_IM;
  75.  
  76.     _SEED ^= RANDOM_MASK;
  77. }
  78.  
  79. void srand_set(int seed)
  80. {
  81.     _SEED = seed;
  82.     srand_cycle();
  83. }
  84.  
  85. float rand(void)
  86. {
  87.     srand_cycle();
  88.     return RANDOM_AM * _SEED;
  89. }
  90.  
  91. float ease_in_exp(float x)
  92. {
  93.     return x <= 0.0 ? 0.0 : pow(2, 10.0 * x - 10.0);
  94. }
  95.  
  96. float ease_in_circ(float x)
  97. {
  98.     return x >= 1.0 ? 1.0 : 1.0 - sqrt(1.0 - x * x);
  99. }
  100.  
  101. float rand_height(void)
  102. {
  103.     float r = ease_in_circ(rand());
  104.     if (rand() < 0.5)
  105.         r *= -1;
  106.  
  107.     return galaxy_params.base_height + (galaxy_params.height * 0.5) * r;
  108. }
  109.  
  110. float rand_height_bulge(float rad)
  111. {
  112.     float r = ease_in_circ(rand());
  113.     if (rand() < 0.5)
  114.         r *= -1;
  115.  
  116.     float bound = (galaxy_params.height * 0.5) + (galaxy_params.height * 0.5) * cos(PI * rad / galaxy_params.bulge_rad);
  117.  
  118.     return galaxy_params.base_height + bound * r;
  119. }
  120.  
  121. float rand_height_bulge_dust(float rad)
  122. {
  123.     float r = ease_in_circ(rand());
  124.     if (rand() < 0.5)
  125.         r *= -1;
  126.  
  127.     float bound = (galaxy_params.height * 0.5) * cos(PI * rad / galaxy_params.bulge_rad);
  128.  
  129.     return galaxy_params.base_height + bound * r;
  130. }
  131.  
  132. bool frustum_check(vec4 pos, float radius)
  133. {
  134.     for (uint i = 0; i < 6; i++)
  135.     {
  136.         if (dot(pos, frustum.planes[i]) + radius < 0.0)
  137.         {
  138.             return false;
  139.         }
  140.     }
  141.  
  142.     return true;
  143. }
  144.  
  145. void main(void)
  146. {
  147.     srand_set(int(gl_GlobalInvocationID.x));
  148.     particle p;
  149.     float speed = galaxy_params.speed;
  150.     uint type = 0;
  151.  
  152.     if (gl_GlobalInvocationID.x < galaxy_params.star_count) // Star
  153.     {
  154.         float rad = ease_in_exp(rand()) * galaxy_params.max_rad;
  155.  
  156.         p.pos = vec2(rad, galaxy_params.eccentricity * rad);
  157.         p.angle = rand() * 2.0 * PI;
  158.         p.tilt = (rad / galaxy_params.max_rad) * galaxy_params.angle;
  159.         p.vel = -speed * sqrt(1.0 / rad);
  160.         p.opacity = galaxy_params.min_star_opacity + (galaxy_params.max_star_opacity - galaxy_params.min_star_opacity) * rand();
  161.         p.temp = galaxy_params.min_temp + (galaxy_params.max_temp - galaxy_params.min_temp) * rand();
  162.  
  163.         if (rad < galaxy_params.bulge_rad)
  164.             p.height = rand_height_bulge(rad);
  165.         else
  166.             p.height = rand_height();
  167.  
  168.         type = 0;
  169.     }
  170.     else // Dust
  171.     {
  172.         float rad;
  173.         if (gl_GlobalInvocationID.x % 2 == 0)
  174.             rad = rand() * galaxy_params.max_rad;
  175.         else
  176.             rad = ease_in_exp(rand()) * galaxy_params.max_rad;
  177.  
  178.         p.pos = vec2(rad, galaxy_params.eccentricity * rad);
  179.         p.angle = rand() * 2.0 * PI;
  180.         p.tilt = (rad / galaxy_params.max_rad) * galaxy_params.angle;
  181.         p.vel = -speed * sqrt(1.0 / rad);
  182.         p.temp = galaxy_params.dust_temp + 2.0 * rad;
  183.         p.opacity = galaxy_params.min_dust_opacity + (galaxy_params.max_dust_opacity - galaxy_params.min_dust_opacity) * rand();
  184.  
  185.         if (rad < galaxy_params.bulge_rad)
  186.             p.height = rand_height_bulge_dust(rad);
  187.         else
  188.             p.height = galaxy_params.base_height;
  189.  
  190.         type = 1;
  191.     }
  192.  
  193.     vec4 pos = {p.pos.x, p.height, p.pos.y, 1.0};
  194.  
  195.     float size = 0.0;
  196.     if (type == 0)  // Star
  197.     {
  198.         size = 10.0;
  199.     }
  200.     else    // Dust
  201.     {
  202.         size = 500.0;
  203.     }
  204.  
  205.     // Cull against stars
  206.     if (frustum_check(pos, size))
  207.     {
  208.         uint draw_cmd_index = atomicAdd(count.draw_count, 1);
  209.         draws.draws[draw_cmd_index].vertex_count = 1;
  210.         draws.draws[draw_cmd_index].instance_count = 1;
  211.         draws.draws[draw_cmd_index].first_instance = 0;
  212.         draws.draws[draw_cmd_index].first_vertex = 0;
  213.         particles.particles[draw_cmd_index] = p;
  214.     }
  215. }
  216.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement