Advertisement
Guest User

Untitled

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