<@if not RENDER_LIGHT_CLUSTER_GRID_SLH@> <@def RENDER_LIGHT_CLUSTER_GRID_SLH@> <@include render-utils/ShaderConstants.h@> struct FrustumGrid { float frustumNear; float rangeNear; float rangeFar; float frustumFar; ivec3 dims; float spare; mat4 eyeToGridProj; mat4 worldToEyeMat; mat4 eyeToWorldMat; }; LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer { FrustumGrid frustumGrid; }; float projection_getNear(mat4 projection) { float planeC = projection[2][3] + projection[2][2]; float planeD = projection[3][2]; return planeD / planeC; } float projection_getFar(mat4 projection) { //float planeA = projection[0][3] - projection[0][2]; All Zeros //float planeB = projection[1][3] - projection[1][2]; All Zeros float planeC = projection[2][3] - projection[2][2]; float planeD = /*projection[3][3]*/ -projection[3][2]; return planeD / planeC; } // glsl / C++ compatible source as interface for FrustrumGrid <@include LightClusterGrid_shared.slh@> // end of hybrid include <@if GLPROFILE == MAC_GL @> #define GRID_NUM_ELEMENTS 4096 #define GRID_INDEX_TYPE ivec4 #define GRID_FETCH_BUFFER(i) i / 4][i % 4 <@else@> #define GRID_NUM_ELEMENTS 4096 #define GRID_INDEX_TYPE ivec4 #define GRID_FETCH_BUFFER(i) i / 4][i % 4 <@endif@> LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer { GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS]; }; LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer { GRID_INDEX_TYPE _clusterGridContent[GRID_NUM_ELEMENTS]; }; ivec3 clusterGrid_getCluster(int index) { int clusterDesc = _clusterGridTable[GRID_FETCH_BUFFER(index)]; int numPointLights = 0xFF & (clusterDesc >> 16); int numSpotLights = 0xFF & (clusterDesc >> 24); int contentOffset = 0xFFFF & (clusterDesc); return ivec3(numPointLights, numSpotLights, contentOffset); } int clusterGrid_getClusterLightId(int index, int offset) { int elementIndex = offset + index; /* int element = _clusterGridContent[GRID_FETCH_BUFFER(elementIndex)]; return element; */ int element = _clusterGridContent[GRID_FETCH_BUFFER((elementIndex >> 1))]; return (element >> (16 * int((elementIndex & 0x00000001) == 1))) & 0x0000FFFF; } <@func fetchClusterInfo(fragWorldPos)@> // From frag world pos find the cluster vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>); ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); int numLights = cluster.x + cluster.y; ivec3 dims = frustumGrid.dims.xyz; <@endfunc@> bool hasLocalLights(int numLights, ivec3 clusterPos, ivec3 dims) { return numLights>0 && all(greaterThanEqual(clusterPos, ivec3(0))) && all(lessThan(clusterPos.xy, dims.xy)) && clusterPos.z <= dims.z; } <@endif@>