<!// LightClusterGrid.slh//// Created by Sam Gateau on 9/8/16.// Copyright 2013 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html!><@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;}; UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID, 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 <!#define GRID_NUM_ELEMENTS 16384#define GRID_INDEX_TYPE int#define GRID_FETCH_BUFFER(i) i!><@endif@> UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID, clusterGridBuffer) { GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS];}; UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT, 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@>
<!
// LightClusterGrid.slh
//
// Created by Sam Gateau on 9/8/16.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
!>
<@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;
};
UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID, 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
<!#define GRID_NUM_ELEMENTS 16384
#define GRID_INDEX_TYPE int
#define GRID_FETCH_BUFFER(i) i!>
<@endif@>
UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID, clusterGridBuffer) {
GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS];
};
UNIFORM_BUFFER(RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT, 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@>