Advertisement
Guest User

Untitled

a guest
Sep 24th, 2019
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. [compute]
  2.  
  3. layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
  4.  
  5. #define NO_CHILDREN 0xFFFFFFFF
  6. #define GREY_VEC vec3(0.33333,0.33333,0.33333)
  7. struct CellPosition {
  8.     uint children[8];
  9. };
  10.  
  11.  
  12. layout(set=0,binding=1,std430) buffer CellPositions {
  13.     CellPosition data[];
  14. } cell_positions;
  15.  
  16. struct CellMaterial {
  17.     uint position; // xyz 10 bits
  18.     uint albedo; //rgb albedo
  19.     uint emission; //rgb normalized with e as multiplier
  20.     uint normal; //RGB normal encoded
  21.     uint level_alpha;
  22. };
  23.  
  24. layout(set=0,binding=2,std430) buffer CellMaterials {
  25.     CellMaterial data[];
  26. } cell_materials;
  27.  
  28. #define LIGHT_TYPE_DIRECTIONAL 0
  29. #define LIGHT_TYPE_OMNI 1
  30. #define LIGHT_TYPE_SPOT 2
  31.  
  32. struct Light {
  33.  
  34.     uint type;
  35.     float energy;
  36.     float radius;
  37.     float attenuation;
  38.  
  39.     vec4 color;
  40.  
  41.     float radius;
  42.     float attenuation;
  43.     float spot_angle_radians;
  44.  
  45.     vec3 position;
  46.     float spot_attenuation;
  47.  
  48.     float advance;
  49.     float max_length;
  50.  
  51.     vec3 direction;
  52.     bool visible;
  53.  
  54.  
  55.     vec4 color;
  56.  
  57.     vec4 clip_planes[3];
  58. };
  59.  
  60. layout(set=0,binding=3,std430) buffer Lights {
  61.     Light data[];
  62. } lights;
  63.  
  64.  
  65. layout(set=0,binding=4,std430) uniform Params {
  66.     vec3 limits;
  67.     uint size;
  68.     uint stack_size;
  69.     uint light_count;
  70.     float emission_scale;
  71. } params;
  72.  
  73.  
  74. layout (rgba8,set=0,binding=5) uniform restrict writeonly image3D color_tex;
  75.  
  76.  
  77. uint raymarch(float distance,float distance_adv,vec3 from,vec3 direction) {
  78.  
  79.     uint result = NO_CHILDREN;
  80.  
  81.     while (distance > -distance_adv) { //use this to avoid precision errors
  82.  
  83.         uint32_t cell = 0;
  84.  
  85.         ivec3 pos = ivec3(from);
  86.         ivec3 ofs = ivec3(0);
  87.         ivec3 half = ivec3(params.size) / 2;
  88.         if (any(lessThan(pos,ivec3(0))) || any(greaterThanEqual(pos,ivec3(params.size)))) {
  89.             return NO_CHILDREN; //outside range
  90.         }
  91.  
  92.         for (int i = 0; i < params.stack_size - 1; i++) {
  93.  
  94.             bvec3 greater = greaterThanEqual(pos,ofs+half);
  95.  
  96.             ofs += mix(ivec3(0),half,greater);
  97.  
  98.             uint child = 0; //wonder if this can be done faster
  99.             if (greater.x) {
  100.                 child|=1;
  101.             }
  102.             if (greater.y) {
  103.                 child|=2;
  104.             }
  105.             if (greater.z) {
  106.                 child|=4;
  107.             }
  108.  
  109.             cell = cell_positions.data[child];
  110.             if (cell == NO_CHILDREN)
  111.                 break;
  112.  
  113.             half >>= ivec3(1);
  114.         }
  115.  
  116.         if ( cell != NO_CHILDREN) {
  117.             return cell; //found cell!
  118.         }
  119.  
  120.         from += direction * distance_adv;
  121.         distance -= distance_adv;
  122.     }
  123.  
  124.     return NO_CHILDREN;
  125. }
  126.  
  127. bool compute_light_vector(uint light,uint cell, vec3 pos,out float attenuation, out vec3 light_pos) {
  128.  
  129.     if (lights.data[light].type==LIGHT_TYPE_DIRECTIONAL) {
  130.  
  131.         vec4 normal = unpackSnorm4x8(cell_materials.data[cell].normal).xyz;
  132.  
  133.         if (normal.z < 0.5 && dot(normal,lights.data[light].direction) >=0.0 ) {
  134.             //not omni-normal and
  135.             return false;
  136.         }
  137.  
  138.         float max_len = params.max_length;
  139.         //TODO clip "to" by planes
  140.         light_pos = lights.data[light].direction * params.max_length;
  141.         attenuation = 1.0;
  142.  
  143.     } else {
  144.  
  145.         light_pos = lights.data[light].position;
  146.         float distance = length(pos - light_pos);
  147.         if (distance >= lights.data[light].radius) {
  148.             return false;
  149.         }
  150.  
  151.         attenuation = pow( distance / lights.data[light].radius + 0.0001, lights.data[light].attenuation );
  152.  
  153.  
  154.         if (lights.data[light].type==LIGHT_TYPE_SPOT) {
  155.  
  156.             vec3 rel = normalize(pos - light_pos);
  157.             float angle = acos(dot(rel,lights.data[light].direction));
  158.             if (angle > lights.data[light].spot_angle_radians) {
  159.                 return false;
  160.             }
  161.  
  162.             float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
  163.             attenuation *= powf(1.0 - d, lights.data[light].spot_attenuation);
  164.         }
  165.     }
  166.  
  167.     return true;
  168. }
  169.  
  170. void main() {
  171.  
  172.     uint cell_index = gl_GlobalInvocationID.x;
  173.  
  174.     uvec3 posu = uvec3(cells.data[cell_index].position&0x3FF,(cells.data[cell_index].position>>10)&0x3FF,cells.data[cell_index].position>>20);
  175.     vec3 pos = vec3(posu);
  176.     float distance_adv = lights.data[light].advance;
  177.  
  178.     vec3 emission = vec3(ivec3(cells.data[cell_index].emission&0x3FF,(cells.data[cell_index].emission>>10)&0x7FF,cells.data[cell_index].emission>>21)) * params.emission_scale;
  179.     vec4 albedo = unpackUnorm4x8(cells.data[cell_index].albedo);
  180.     vec4 normal = unpackSnorm4x8(cells.data[cell_index].normal); //w >0.5 means, all directions
  181.  
  182. #ifdef MODE_ANISOTROPIC
  183.     vec3 accum[6]=vec3[](vec3(0.0),vec3(0.0),vec3(0.0),vec3(0.0),vec3(0.0),vec3(0.0));
  184.     const vec3 accum_dirs[6]=vec3[](vec3(1.0,0.0,0.0),vec3(-1.0,0.0,0.0),vec3(0.0,1.0,0.0),vec3(0.0,-1.0,0.0),vec3(0.0,0.0,1.0),vec3(0.0,0.0,-1.0));
  185. #else
  186.     vec3 accum = vec3(0);
  187. #endif
  188.  
  189.     for(uint i=0;i<params.light_count;i++) {
  190.  
  191.         float attenuation;
  192.         vec3 light_pos;
  193.  
  194.         if (!compute_light_vector(i,cell_index,pos,attenuation,light_pos)) {
  195.             continue;
  196.         }
  197.  
  198.         vec3 light_dir = pos - light_pos;
  199.         float distance = length(light_dir);
  200.  
  201.         light_dir=normalize(light_dir);
  202.  
  203.         distance += distance_adv - mod(distance, distance_adv); //make it reach the center of the box always
  204.  
  205.         vec3 from = pos - light_dir * distance; //approximate
  206.  
  207.         if (normal.w < 0.5 && dot(normal.xyz,light_dir)>=0) {
  208.             continue; //not facing the light
  209.         }
  210.  
  211.         uint result = raymarch(distance,distance_adv,from,lights.data[light].direction);
  212.  
  213.         if (result != cell_index) {
  214.             continue; //was occluded
  215.         }
  216.  
  217.         vec3 light = lights.data[i].color * albedo.rgb * attenuation;
  218.  
  219. #ifdef MODE_ANISOTROPIC
  220.         for(uint j=0;j<6;j++) {
  221.             accum[j]+=max(0.0,dot(accum_dir,-light_dir))*light+emission;
  222.         }
  223. #else
  224.         if (normal.w < 0.5) {
  225.             accum+=max(0.0,dot(normal.xyz,-light_dir))*light+emission;
  226.         } else {
  227.             //all directions
  228.             accum+=light+emission;
  229.         }
  230. #endif
  231.  
  232.     }
  233.  
  234. #ifdef MODE_ANISOTROPIC
  235.  
  236.     vec3 accum_total = accum[0]+accum[1]+accum[2]+accum[3]+accum[4]+accum[5];
  237.     float accum_total_energy = max(dot(accum_total,GREY_VEC),0.00001);
  238.     vec3 iso_positive = vec3(dot(aniso[0],GREY_VEC),dot(aniso[2],GREY_VEC),dot(aniso[4],GREY_VEC))/vec3(accum_total_energy);
  239.     vec3 iso_negative = vec3(dot(aniso[1],GREY_VEC),dot(aniso[3],GREY_VEC),dot(aniso[5],GREY_VEC))/vec3(accum_total_energy);
  240.  
  241.     //store in 3D textures, total color, and isotropic magnitudes
  242. #else
  243.     //store in 3D texture pos, accum
  244.     imageStore(color_tex,uvec4(posu,0),vec4(accum,albedo.a));
  245. #endif
  246.  
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement