Advertisement
Guest User

Untitled

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