143 lines
4.0 KiB
Plaintext
143 lines
4.0 KiB
Plaintext
#version 460
|
|
#extension GL_ARB_gpu_shader_int64 : enable
|
|
|
|
layout(local_size_x = 128, local_size_y = 1, local_size_x = 1) in;
|
|
|
|
#import <zenith:lod/gl46/quad_format.glsl>
|
|
#import <zenith:lod/gl46/bindings.glsl>
|
|
#import <zenith:lod/gl46/frustum.glsl>
|
|
#import <zenith:lod/gl46/section.glsl>
|
|
#line 11
|
|
|
|
//https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_shader_16bit_storage.txt
|
|
// adds support for uint8_t which can use for compact visibility buffer
|
|
|
|
|
|
|
|
/*
|
|
uint count;
|
|
uint instanceCount;
|
|
uint firstIndex;
|
|
int baseVertex;
|
|
uint baseInstance;
|
|
*/
|
|
|
|
uint encodeLocalLodPos(uint detail, ivec3 pos) {
|
|
uvec3 detla = (pos - (baseSectionPos >> detail))&((1<<9)-1);
|
|
return (detail<<29)|(detla.x<<20)|(detla.y<<11)|(detla.z<<2);
|
|
}
|
|
|
|
|
|
//Note: if i want reverse indexing i need to use the index buffer offset to offset
|
|
void writeCmd(uint idx, uint encodedPos, uint offset, uint quadCount) {
|
|
DrawCommand cmd;
|
|
cmd.count = quadCount * 6;
|
|
cmd.instanceCount = 1;
|
|
cmd.firstIndex = 0;
|
|
cmd.baseVertex = int(offset)<<2;
|
|
cmd.baseInstance = encodedPos;
|
|
cmdBuffer[idx] = cmd;
|
|
}
|
|
|
|
void main() {
|
|
if (gl_GlobalInvocationID.x >= sectionCount) {
|
|
return;
|
|
}
|
|
SectionMeta meta = sectionData[gl_GlobalInvocationID.x];
|
|
uint detail = extractDetail(meta);
|
|
ivec3 ipos = extractPosition(meta);
|
|
|
|
vec3 cornerPos = vec3(((ipos<<detail)-baseSectionPos)<<5)-cameraSubPos;
|
|
|
|
|
|
//Check the occlusion data from last frame
|
|
bool shouldRender = visibilityData[gl_GlobalInvocationID.x] == frameId - 1;
|
|
|
|
//Clear the occlusion data (not strictly? needed? i think???)
|
|
//visibilityData[gl_GlobalInvocationID.x] = 0;
|
|
|
|
//TODO: need to make it check that only if it was also in the frustum last frame does it apply the visibilityData check!
|
|
// this fixes temporal coherance
|
|
|
|
//This prevents overflow of the relative position encoder
|
|
if (shouldRender) {
|
|
shouldRender = !any(lessThan(ivec3(254), abs(ipos-(baseSectionPos>>detail))));
|
|
}
|
|
|
|
if (shouldRender) {
|
|
uint encodedPos = encodeLocalLodPos(detail, ipos);
|
|
uint ptr = extractQuadStart(meta);
|
|
ivec3 relative = ipos-(baseSectionPos>>detail);
|
|
|
|
|
|
|
|
//TODO:FIXME: Figure out why these are in such a weird order
|
|
uint msk = 0;
|
|
msk |= uint(relative.y>-1)<<0;
|
|
msk |= uint(relative.y<1 )<<1;
|
|
msk |= uint(relative.z>-1)<<2;
|
|
msk |= uint(relative.z<1 )<<3;
|
|
msk |= uint(relative.x>-1)<<4;
|
|
msk |= uint(relative.x<1 )<<5;
|
|
|
|
|
|
uint cmdPtr = atomicAdd(opaqueDrawCount, bitCount(msk)+1);
|
|
|
|
|
|
uint count = 0;
|
|
//Translucency
|
|
count = meta.cntA&0xFFFF;
|
|
if (count != 0) {
|
|
uint translucentCommandPtr = atomicAdd(translucentDrawCount, 1) + 400000;//FIXME: dont hardcode this offset
|
|
writeCmd(translucentCommandPtr, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//Double sided quads
|
|
count = (meta.cntA>>16)&0xFFFF;
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
ptr += count;
|
|
|
|
//Down
|
|
count = (meta.cntB)&0xFFFF;
|
|
if ((msk&(1<<0))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//Up
|
|
count = (meta.cntB>>16)&0xFFFF;
|
|
if ((msk&(1<<1))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//North
|
|
count = (meta.cntC)&0xFFFF;
|
|
if ((msk&(1<<2))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//South
|
|
count = (meta.cntC>>16)&0xFFFF;
|
|
if ((msk&(1<<3))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//West
|
|
count = (meta.cntD)&0xFFFF;
|
|
if ((msk&(1<<4))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
|
|
//East
|
|
count = (meta.cntD>>16)&0xFFFF;
|
|
if ((msk&(1<<5))!=0) {
|
|
writeCmd(cmdPtr++, encodedPos, ptr, count);
|
|
}
|
|
ptr += count;
|
|
}
|
|
} |