<@if not RENDER_LIGHT_CLUSTER_GRID_SLH@> <@def RENDER_LIGHT_CLUSTER_GRID_SLH@> struct FrustumGrid { float frustumNear; float rangeNear; float rangeFar; float frustumFar; ivec3 dims; float spare; mat4 eyeToGridProj; mat4 worldToEyeMat; mat4 eyeToWorldMat; }; 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 uniform clusterGridBuffer { int _clusterGridTable[16384]; }; uniform clusterContentBuffer { int _clusterGridContent[16384]; }; ivec3 clusterGrid_getCluster(int index) { int clusterDesc = _clusterGridTable[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, ivec2 cluster) { int arrayElement = cluster.y + index; int element = _clusterGridContent[arrayElement]; return element; // int element = _clusterGridContent[arrayElement >> 1]; // return (((arrayElement & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF; } <@endif@>