| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /*
- * Copyright 2018 Kostas Anagnostou. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
- */
- #include "bgfx_compute.sh"
- SAMPLER2D(s_texOcclusionDepth, 0);
- BUFFER_RO(instanceDataIn, vec4, 1);
- BUFFER_RW(drawcallInstanceCount, uint, 2);
- BUFFER_WO(instancePredicates, bool, 3);
- uniform vec4 u_inputRTSize;
- uniform vec4 u_cullingConfig;
- NUM_THREADS(64, 1, 1)
- void main()
- {
- bool predicate = false;
- //make sure that we not processing more instances than available
- if (gl_GlobalInvocationID.x < uint(u_cullingConfig.x) )
- {
- //get the bounding box for this instance
- vec4 bboxMin = instanceDataIn[2 * gl_GlobalInvocationID.x] ;
- vec3 bboxMax = instanceDataIn[2 * gl_GlobalInvocationID.x + 1].xyz;
- int drawcallID = int(bboxMin.w);
- //Adapted from http://blog.selfshadow.com/publications/practical-visibility/
- vec3 bboxSize = bboxMax.xyz - bboxMin.xyz;
- vec3 boxCorners[] = {
- bboxMin.xyz,
- bboxMin.xyz + vec3(bboxSize.x,0,0),
- bboxMin.xyz + vec3(0, bboxSize.y,0),
- bboxMin.xyz + vec3(0, 0, bboxSize.z),
- bboxMin.xyz + vec3(bboxSize.xy,0),
- bboxMin.xyz + vec3(0, bboxSize.yz),
- bboxMin.xyz + vec3(bboxSize.x, 0, bboxSize.z),
- bboxMin.xyz + bboxSize.xyz
- };
- float minZ = 1.0;
- vec2 minXY = vec2(1.0, 1.0);
- vec2 maxXY = vec2(0.0, 0.0);
- UNROLL
- for (int i = 0; i < 8; i++)
- {
- //transform World space aaBox to NDC
- vec4 clipPos = mul( u_viewProj, vec4(boxCorners[i], 1) );
- #if BGFX_SHADER_LANGUAGE_GLSL
- clipPos.z = 0.5 * ( clipPos.z + clipPos.w );
- #endif
- clipPos.z = max(clipPos.z, 0);
- clipPos.xyz = clipPos.xyz / clipPos.w;
- clipPos.xy = clamp(clipPos.xy, -1, 1);
- clipPos.xy = clipPos.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);
- minXY = min(clipPos.xy, minXY);
- maxXY = max(clipPos.xy, maxXY);
- minZ = saturate(min(minZ, clipPos.z));
- }
- vec4 boxUVs = vec4(minXY, maxXY);
- // Calculate hi-Z buffer mip
- ivec2 size = ivec2( (maxXY - minXY) * u_inputRTSize.xy);
- float mip = ceil(log2(max(size.x, size.y)));
- mip = clamp(mip, 0, u_cullingConfig.z);
- // Texel footprint for the lower (finer-grained) level
- float level_lower = max(mip - 1, 0);
- vec2 scale = vec2_splat(exp2(-level_lower) );
- vec2 a = floor(boxUVs.xy*scale);
- vec2 b = ceil(boxUVs.zw*scale);
- vec2 dims = b - a;
- // Use the lower level if we only touch <= 2 texels in both dimensions
- if (dims.x <= 2 && dims.y <= 2)
- mip = level_lower;
- #if BGFX_SHADER_LANGUAGE_GLSL
- boxUVs.y = 1.0 - boxUVs.y;
- boxUVs.w = 1.0 - boxUVs.w;
- #endif
- //load depths from high z buffer
- vec4 depth =
- {
- texture2DLod(s_texOcclusionDepth, boxUVs.xy, mip).x,
- texture2DLod(s_texOcclusionDepth, boxUVs.zy, mip).x,
- texture2DLod(s_texOcclusionDepth, boxUVs.xw, mip).x,
- texture2DLod(s_texOcclusionDepth, boxUVs.zw, mip).x,
- };
- //find the max depth
- float maxDepth = max( max(depth.x, depth.y), max(depth.z, depth.w) );
- if ( minZ <= maxDepth )
- {
- predicate = true;
- //increase instance count for this particular prop type
- atomicAdd(drawcallInstanceCount[ drawcallID ], 1);
- }
- }
- instancePredicates[gl_GlobalInvocationID.x] = predicate;
- }
|