Files
voxy/src/main/resources/assets/zenith/shaders/lod/gl46/cmdgen.comp
2024-01-29 15:39:48 +10:00

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;
}
}