Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Calculate per tile depth mask for 2.5D light culling
- */
- /**/
- //depth partitioning
- //[ min | min + (1*range/32) | min + (2*range/32) | ... | max ]
- //local_depth_mask: depth mask to be computed
- //max_depth: max depth per tile [0...1]
- //min_depth: min depth per tile [0...1]
- //raw_depth.x: actual depth per pixel [0...1]
- //view space values
- float vs_min_depth = min_depth * -far;
- float vs_max_depth = max_depth * -far;
- float vs_depth = raw_depth.x * -far;
- //depth range in each tile
- float range = fabs( //calculate using view space depth
- vs_max_depth -
- vs_min_depth +
- //add a bit to the range so that the first and last buckets will be occupied
- 0.00001f ) / 32.0f;
- vs_depth -= vs_min_depth; //so that min = 0 (it'll be in the 0th bucket)
- float depth_slot = floor(vs_depth / range); //which slot is this pixel in?
- if( !early_rejection ) //if not skybox
- {
- //determine per tile depth mask
- //depth_mask = depth_mask | (1 << depth_slot)
- atomic_or( &local_depth_mask, 1 << (uint)(depth_slot) );
- }
- //need a barrier here as we tampered with LDS
- barrier( CLK_LOCAL_MEM_FENCE );
- /**/
- /*
- * Per light calculations (one light per thread)
- */
- //cull each light per tile, each thread in a tile processes one light
- for( int c = workgroup_index; c < num_of_lights; c += local_size.x * local_size.y )
- {
- bool in_frustum = true;
- float att_end = in_lights[c].attenuation_end; //sort of like light radius
- float3 light_pos = vload3( 0, in_lights[c].position ); //view space light pos
- /**/
- //calculate per light bitmask
- uint light_bitmask = 0;
- float light_z_min = -(light_pos.z + att_end); //light z min
- float light_z_max = -(light_pos.z - att_end); //light z max
- light_z_min -= vs_min_depth; //so that min = 0
- light_z_max -= vs_min_depth; //so that min = 0
- float depth_slot_min = floor(light_z_min / range);
- float depth_slot_max = floor(light_z_max / range);
- //if the light is inside the depth range
- if( !( ( depth_slot_max > 31.0f &&
- depth_slot_min > 31.0f ) ||
- ( depth_slot_min < 0.0f &&
- depth_slot_max < 0.0f ) ) )
- {
- if( depth_slot_max > 30.0f ) //if the light's max is beyond the whole range
- light_bitmask = (uint)(~0); //set each bit to 1
- else
- //set the bit (max + 1) to 1, then subtract 1 to make all the lower bits 1s
- light_bitmask = (1 << ((uint)(depth_slot_max) + 1)) - 1;
- if( depth_slot_min > 0.0f )
- //correct the bitmask if the light's min is not the 0th slot
- light_bitmask -= (1 << (uint)(depth_slot_min)) - 1;
- }
- in_frustum = in_frustum && (local_depth_mask & light_bitmask);
- /**/
- //some more culling here...
- if( in_frustum )
- {
- int index = atomic_inc( &local_num_of_lights ); //set number of lights in tile
- local_lights[index] = c; //assign light index to tile
- }
- }
- //need a barrier here as we tampered with LDS
- barrier( CLK_LOCAL_MEM_FENCE );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement