mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 02:07:24 +02:00
109 lines
3.3 KiB
Text
109 lines
3.3 KiB
Text
<!
|
|
// 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;
|
|
};
|
|
|
|
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
|
|
|
|
<!#define GRID_NUM_ELEMENTS 16384
|
|
#define GRID_INDEX_TYPE int
|
|
#define GRID_FETCH_BUFFER(i) i!>
|
|
<@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@>
|