Advertisement
Guest User

Untitled

a guest
Oct 7th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. [compute]
  2.  
  3. #version 450
  4.  
  5. VERSION_DEFINES
  6.  
  7. layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
  8.  
  9. #define MAX_DISTANCE 100000
  10.  
  11. #define NO_CHILDREN 0xFFFFFFFF
  12. #define GREY_VEC vec3(0.33333,0.33333,0.33333)
  13.  
  14. struct CellChildren {
  15.     uint children[8];
  16. };
  17.  
  18. layout(set=0,binding=1,std430) buffer CellChildrenBuffer {
  19.     CellChildren data[];
  20. } cell_children;
  21.  
  22.  
  23. struct CellData {
  24.     uint position; // xyz 10 bits
  25.     uint albedo; //rgb albedo
  26.     uint emission; //rgb normalized with e as multiplier
  27.     uint normal; //RGB normal encoded
  28. };
  29.  
  30. layout(set=0,binding=2,std430) buffer CellDataBuffer {
  31.     CellData data[];
  32. } cell_data;
  33.  
  34. layout (r8ui,set=0,binding=3) uniform restrict writeonly uimage3D sdf_tex;
  35.  
  36. layout(push_constant, binding = 0, std430) uniform Params {
  37.  
  38.     ivec3 limits;
  39.     uint stack_size;
  40. } params;
  41.  
  42.  
  43. float distance_to_aabb(ivec3 pos, ivec3 aabb_pos, ivec3 aabb_size) {
  44.  
  45.     vec3 delta = vec3(max(ivec3(0),max(aabb_pos - pos, pos - (aabb_pos + aabb_size - ivec3(1)))));
  46.     return length(delta);
  47. }
  48.  
  49. void main() {
  50.  
  51.     ivec3 pos = ivec3(gl_GlobalInvocationID);
  52.  
  53.     uint stack[10]=uint[](0,0,0,0,0,0,0,0,0,0);
  54.     uint stack_indices[10]=uint[](0,0,0,0,0,0,0,0,0,0);
  55.     ivec3 stack_positions[10]=ivec3[](ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0),ivec3(0));
  56.  
  57.     bool cell_found = false;
  58.     bool cell_found_exact = false;
  59.     ivec3 closest_cell_pos;
  60.     float closest_distance = MAX_DISTANCE;
  61.     int stack_pos = 0;
  62.  
  63.     while(true) {
  64.  
  65.         uint index = stack_indices[stack_pos];
  66.  
  67.         ivec3 cell_size = params.limits >> stack_pos;
  68.         ivec3 cell_pos = stack_positions[stack_pos];
  69.  
  70.         if (index==0) {
  71.             //enter stack (going down), need to set up this stack level
  72. #if 0
  73.  
  74.             uint found = 0;
  75.             for(uint i=0;i<8;i++) {
  76.                 if (cell_children.data[stack[stack_pos]].children[i] != NO_CHILDREN) {
  77.                     index|=(i<<(found*3));
  78.                     found++;
  79.                 }
  80.             }
  81.  
  82.             index |= found<<24;
  83. #else
  84.  
  85.             uint order[8]=uint[](0,1,2,3,4,5,6,7);
  86.  
  87.             ivec3 dir = ( pos - ( cell_pos + (cell_size >>1) ) );
  88.             if (dir.x > 0) {
  89.                 uint tmp = order[0];
  90.                 order[0]=order[1];
  91.                 order[1]=tmp;
  92.  
  93.                 tmp = order[2];
  94.                 order[2]=order[3];
  95.                 order[3]=tmp;
  96.  
  97.                 tmp = order[4];
  98.                 order[4]=order[5];
  99.                 order[5]=tmp;
  100.  
  101.                 tmp = order[6];
  102.                 order[6]=order[7];
  103.                 order[7]=tmp;
  104.  
  105.             }
  106.  
  107.             if (dir.y > 0) {
  108.                 uint tmp = order[0];
  109.                 order[0]=order[2];
  110.                 order[2]=tmp;
  111.  
  112.                 tmp = order[1];
  113.                 order[1]=order[3];
  114.                 order[3]=tmp;
  115.  
  116.                 tmp = order[4];
  117.                 order[4]=order[6];
  118.                 order[6]=tmp;
  119.  
  120.                 tmp = order[5];
  121.                 order[5]=order[7];
  122.                 order[7]=tmp;
  123.  
  124.             }
  125.  
  126.  
  127.             if (dir.z > 0) {
  128.                 uint tmp = order[0];
  129.                 order[0]=order[4];
  130.                 order[4]=tmp;
  131.  
  132.                 tmp = order[1];
  133.                 order[1]=order[5];
  134.                 order[5]=tmp;
  135.  
  136.                 tmp = order[2];
  137.                 order[2]=order[6];
  138.                 order[6]=tmp;
  139.  
  140.                 tmp = order[3];
  141.                 order[3]=order[7];
  142.                 order[7]=tmp;
  143.  
  144.             }
  145.  
  146.             uint found = 0;
  147.             for(uint i=0;i<8;i++) {
  148.                 uint idx = order[i];
  149.                 if (cell_children.data[stack[stack_pos]].children[idx] != NO_CHILDREN) {
  150.                     index|=(idx<<(found*3));
  151.                     found++;
  152.                 }
  153.             }
  154.  
  155.             index |= found<<24;
  156.  
  157. #endif
  158.         }
  159.  
  160.         //octree traversal
  161.         uint current_child = (index>>27)&0x7;
  162.         uint current_count = (index>>24)&0x7;
  163.  
  164.         if (current_child == current_count) {
  165.             //go up
  166.             if (stack_pos==0) {
  167.                 break; //done going through octree
  168.             }
  169.             stack_pos--;
  170.             continue;
  171.         }
  172.  
  173.         index=(index&((1<<27)-1))|(current_child+1); //increment current child
  174.  
  175.         stack_indices[stack_pos] = index; //store back index
  176.  
  177.         uint child_index = (index>>(current_child*3))&0x7;
  178.         //create child AABB
  179.  
  180.         ivec3 child_cell_size = cell_size >> 1;
  181.         ivec3 child_cell_pos = cell_pos;
  182.         child_cell_pos+=mix(ivec3(0),child_cell_size,bvec3(uvec3(child_index&1,child_index&2,child_index&4)!=uvec3(0)));
  183.  
  184.         bool is_leaf = stack_pos == (params.stack_size-2);
  185.  
  186.         if (child_cell_pos==pos && is_leaf) {
  187.             //we may actually end up in the exact cell.
  188.             //if this happens, just abort
  189.             cell_found_exact=true;
  190.             break;
  191.         }
  192.  
  193.         if (cell_found) {
  194.             //discard by distance
  195.             float distance = distance_to_aabb(pos,child_cell_pos,child_cell_size);
  196.             if (distance >= closest_distance) {
  197.                 continue; //pointless, just test next child
  198.             } else if (is_leaf) {
  199.                 //closer than what we have AND end of stack, save and continue
  200.                 closest_cell_pos = child_cell_pos;
  201.                 closest_distance = distance;
  202.                 continue;
  203.             }
  204.         } else if (is_leaf) {
  205.             //first solid cell we find, save and continue
  206.             closest_distance = distance_to_aabb(pos,child_cell_pos,child_cell_size);
  207.             closest_cell_pos = child_cell_pos;
  208.             cell_found=true;
  209.             continue;
  210.         }
  211.  
  212.  
  213.         stack[stack_pos+1]=cell_children.data[stack[stack_pos]].children[child_index];
  214.         stack_indices[stack_pos+1]=0; //forces regen
  215.         stack_positions[stack_pos+1]=child_cell_pos;
  216.         stack_pos++; //go up stack
  217.  
  218.     }
  219.  
  220.     uint dist_8;
  221.  
  222.     if (cell_found_exact) {
  223.         dist_8=0; //equals to -1
  224.     } else {
  225.         float closest_distance = length(vec3(pos-closest_cell_pos));
  226.         dist_8 = clamp(uint(closest_distance),0,254) + 1; //conservative, 0 is 1, so <1 is considered solid
  227.     }
  228.  
  229.     imageStore(sdf_tex,pos,uvec4(dist_8));
  230.  
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement