Advertisement
Guest User

Untitled

a guest
Apr 18th, 2014
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.   /*
  2.    * Calculate per tile depth mask for 2.5D light culling
  3.    */
  4.    
  5.   /**/
  6.   //depth partitioning
  7.   //[ min | min + (1*range/32) | min + (2*range/32) | ... | max ]
  8.  
  9.   //local_depth_mask: depth mask to be computed
  10.   //max_depth: max depth per tile [0...1]
  11.   //min_depth: min depth per tile [0...1]
  12.   //raw_depth.x: actual depth per pixel [0...1]
  13.  
  14.   //view space values
  15.   float vs_min_depth = min_depth * -far;
  16.   float vs_max_depth = max_depth * -far;
  17.   float vs_depth = raw_depth.x * -far;
  18.  
  19.   //depth range in each tile
  20.   float range = fabs( //calculate using view space depth
  21.                       vs_max_depth -
  22.                       vs_min_depth +
  23.                       //add a bit to the range so that the first and last buckets will be occupied
  24.                       0.00001f ) / 32.0f;
  25.                      
  26.   vs_depth -= vs_min_depth; //so that min = 0 (it'll be in the 0th bucket)
  27.   float depth_slot = floor(vs_depth / range); //which slot is this pixel in?
  28.  
  29.   if( !early_rejection ) //if not skybox
  30.   {
  31.     //determine per tile depth mask
  32.     //depth_mask = depth_mask | (1 << depth_slot)
  33.     atomic_or( &local_depth_mask, 1 << (uint)(depth_slot) );
  34.   }
  35.  
  36.   //need a barrier here as we tampered with LDS
  37.   barrier( CLK_LOCAL_MEM_FENCE );
  38.   /**/
  39.  
  40.   /*
  41.    * Per light calculations (one light per thread)
  42.    */
  43.  
  44.   //cull each light per tile, each thread in a tile processes one light
  45.   for( int c = workgroup_index; c < num_of_lights; c += local_size.x * local_size.y )
  46.   {
  47.     bool in_frustum = true;
  48.    
  49.     float att_end = in_lights[c].attenuation_end; //sort of like light radius
  50.     float3 light_pos = vload3( 0, in_lights[c].position ); //view space light pos
  51.    
  52.     /**/
  53.     //calculate per light bitmask
  54.     uint light_bitmask = 0;
  55.  
  56.     float light_z_min = -(light_pos.z + att_end); //light z min
  57.     float light_z_max = -(light_pos.z - att_end); //light z max
  58.     light_z_min -= vs_min_depth; //so that min = 0
  59.     light_z_max -= vs_min_depth; //so that min = 0
  60.     float depth_slot_min = floor(light_z_min / range);
  61.     float depth_slot_max = floor(light_z_max / range);
  62.  
  63.     //if the light is inside the depth range
  64.     if( !( ( depth_slot_max > 31.0f &&
  65.               depth_slot_min > 31.0f ) ||
  66.             ( depth_slot_min < 0.0f &&
  67.               depth_slot_max < 0.0f ) ) )
  68.     {
  69.       if( depth_slot_max > 30.0f ) //if the light's max is beyond the whole range
  70.         light_bitmask = (uint)(~0); //set each bit to 1
  71.       else
  72.         //set the bit (max + 1) to 1, then subtract 1 to make all the lower bits 1s
  73.         light_bitmask = (1 << ((uint)(depth_slot_max) + 1)) - 1;
  74.            
  75.       if( depth_slot_min > 0.0f )
  76.         //correct the bitmask if the light's min is not the 0th slot
  77.         light_bitmask -= (1 << (uint)(depth_slot_min)) - 1;
  78.     }
  79.        
  80.     in_frustum = in_frustum && (local_depth_mask & light_bitmask);
  81.     /**/
  82.    
  83.     //some more culling here...
  84.  
  85.     if( in_frustum )
  86.     {
  87.       int index = atomic_inc( &local_num_of_lights ); //set number of lights in tile
  88.       local_lights[index] = c; //assign light index to tile
  89.     }
  90.   }
  91.  
  92.   //need a barrier here as we tampered with LDS
  93.   barrier( CLK_LOCAL_MEM_FENCE );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement