Initial commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
struct Frustum {
|
||||
vec4 planes[6];
|
||||
};
|
||||
|
||||
layout(binding = 0, std140) uniform SceneUniform {
|
||||
mat4 MVP;
|
||||
ivec3 baseSectionPos;
|
||||
int sectionCount;
|
||||
Frustum frustum;
|
||||
vec3 cameraSubPos;
|
||||
int _padA;
|
||||
};
|
||||
|
||||
struct State {
|
||||
uint biomeTintMsk;
|
||||
uint faceColours[6];
|
||||
};
|
||||
|
||||
struct Biome {
|
||||
uint foliage;
|
||||
uint water;
|
||||
};
|
||||
|
||||
struct SectionMeta {
|
||||
uvec4 header;
|
||||
uvec4 drawdata;
|
||||
};
|
||||
|
||||
//TODO: see if making the stride 2*4*4 bytes or something cause you get that 16 byte write
|
||||
struct DrawCommand {
|
||||
uint count;
|
||||
uint instanceCount;
|
||||
uint firstIndex;
|
||||
int baseVertex;
|
||||
uint baseInstance;
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) readonly restrict buffer QuadBuffer {
|
||||
Quad quadData[];
|
||||
};
|
||||
|
||||
layout(binding = 2, std430) writeonly restrict buffer DrawBuffer {
|
||||
DrawCommand cmdBuffer[];
|
||||
};
|
||||
|
||||
layout(binding = 3, std430) readonly restrict buffer SectionBuffer {
|
||||
SectionMeta sectionData[];
|
||||
};
|
||||
|
||||
layout(binding = 4, std430) readonly restrict buffer StateBuffer {
|
||||
State stateData[];
|
||||
};
|
||||
|
||||
layout(binding = 5, std430) readonly restrict buffer BiomeBuffer {
|
||||
Biome biomeData[];
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
#version 460
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
#import <voxelmon:lod/gl46/quad_format.glsl>
|
||||
#import <voxelmon:lod/gl46/bindings.glsl>
|
||||
|
||||
//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
|
||||
|
||||
layout(local_size_x = 128, local_size_y = 1, local_size_x = 1) in;
|
||||
|
||||
|
||||
bool testFrustumPoint(vec4 plane, vec3 min, vec3 max) {
|
||||
vec3 point = mix(max, min, lessThan(plane.xyz, vec3(0))) * plane.xyz;
|
||||
return (point.x + point.y + point.z) >= -plane.w;
|
||||
}
|
||||
|
||||
bool testFrustum(Frustum frust, vec3 min, vec3 max) {
|
||||
return testFrustumPoint(frust.planes[0], min, max) &&
|
||||
testFrustumPoint(frust.planes[1], min, max) &&
|
||||
testFrustumPoint(frust.planes[2], min, max) &&
|
||||
testFrustumPoint(frust.planes[3], min, max) &&
|
||||
testFrustumPoint(frust.planes[4], min, max) &&
|
||||
testFrustumPoint(frust.planes[5], min, max);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint extractDetail(SectionMeta section) {
|
||||
return section.header.x>>28;
|
||||
}
|
||||
|
||||
/*
|
||||
uint count;
|
||||
uint instanceCount;
|
||||
uint firstIndex;
|
||||
int baseVertex;
|
||||
uint baseInstance;
|
||||
*/
|
||||
ivec3 extractPosition(SectionMeta section) {
|
||||
int y = ((int(section.header.x)<<4)>>24);
|
||||
int x = (int(section.header.y)<<4)>>8;
|
||||
int z = int((section.header.x&((1<<20)-1))<<4);
|
||||
z |= int(section.header.y>>28);
|
||||
z <<= 8;
|
||||
z >>= 8;
|
||||
return ivec3(x,y,z);
|
||||
}
|
||||
uint extractQuadStart(SectionMeta meta) {
|
||||
return meta.header.z;
|
||||
}
|
||||
|
||||
uint extractQuadCount(SectionMeta meta) {
|
||||
return meta.header.w;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void main() {
|
||||
if (gl_GlobalInvocationID.x >= sectionCount) {
|
||||
return;
|
||||
}
|
||||
SectionMeta meta = sectionData[gl_GlobalInvocationID.x];
|
||||
uint detail = extractDetail(meta);
|
||||
ivec3 ipos = extractPosition(meta);
|
||||
|
||||
//TODO: fixme; i dont think this is correct
|
||||
vec3 cornerPos = vec3(((ipos<<detail)-baseSectionPos)<<5)-cameraSubPos;
|
||||
|
||||
|
||||
bool shouldRender = testFrustum(frustum, cornerPos, cornerPos+vec3(1<<(detail+5)));
|
||||
|
||||
//This prevents overflow of the relative position encoder
|
||||
if (shouldRender) {
|
||||
shouldRender = !any(lessThan(ivec3(254), abs(ipos-(baseSectionPos>>detail))));
|
||||
}
|
||||
|
||||
if (shouldRender) {
|
||||
DrawCommand cmd;
|
||||
cmd.count = extractQuadCount(meta) * 6;
|
||||
cmd.instanceCount = 1;
|
||||
cmd.firstIndex = 0;
|
||||
cmd.baseVertex = int(extractQuadStart(meta))<<2;
|
||||
cmd.baseInstance = encodeLocalLodPos(detail, ipos);
|
||||
cmdBuffer[gl_GlobalInvocationID.x] = cmd;
|
||||
} else {
|
||||
DrawCommand cmd;
|
||||
cmd.count = 0;
|
||||
cmd.instanceCount = 0;
|
||||
cmd.firstIndex = 0;
|
||||
cmd.baseVertex = 0;
|
||||
cmd.baseInstance = 0;
|
||||
cmdBuffer[gl_GlobalInvocationID.x] = cmd;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#version 460 core
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
#import <voxelmon:lod/gl46/bindings.glsl>
|
||||
@@ -0,0 +1,4 @@
|
||||
#version 460 core
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
#import <voxelmon:lod/gl46/bindings.glsl>
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifdef GL_ARB_gpu_shader_int64
|
||||
#define Quad uint64_t
|
||||
|
||||
#define Eu32(data, amountBits, shift) (uint((data)>>(shift))&((1u<<(amountBits))-1))
|
||||
|
||||
vec3 extractPos(uint64_t quad) {
|
||||
//TODO: pull out the majic constants into #defines (specifically the shift amount)
|
||||
return vec3(Eu32(quad, 5, 21), Eu32(quad, 5, 16), Eu32(quad, 5, 11));
|
||||
}
|
||||
|
||||
ivec2 extractSize(uint64_t quad) {
|
||||
return ivec2(Eu32(quad, 4, 3), Eu32(quad, 4, 7)) + ivec2(1);//the + 1 is cause you cant actually have a 0 size quad
|
||||
}
|
||||
|
||||
uint extractFace(uint64_t quad) {
|
||||
return Eu32(quad, 3, 0);
|
||||
}
|
||||
|
||||
uint extractStateId(uint64_t quad) {
|
||||
return Eu32(quad, 20, 26);
|
||||
}
|
||||
|
||||
uint extractBiomeId(uint64_t quad) {
|
||||
return Eu32(quad, 9, 46);
|
||||
}
|
||||
|
||||
uint extractLightId(uint64_t quad) {
|
||||
return Eu32(quad, 8, 55);
|
||||
}
|
||||
|
||||
#else
|
||||
//TODO: FIXME, ivec2 swaps around the data of the x and y cause its written in little endian
|
||||
|
||||
#define Quad ivec2
|
||||
|
||||
#define Eu32(data, amountBits, shift) (uint((data)>>(shift))&((1u<<(amountBits))-1))
|
||||
|
||||
vec3 extractPos(ivec2 quad) {
|
||||
return vec3(Eu32(quad.y, 5, 21), Eu32(quad.y, 5, 16), Eu32(quad.y, 5, 11));
|
||||
}
|
||||
|
||||
ivec2 extractSize(ivec2 quad) {
|
||||
return ivec2(Eu32(quad.y, 4, 3), Eu32(quad.y, 4, 7)) + ivec2(1);//the + 1 is cause you cant actually have a 0 size quad
|
||||
}
|
||||
|
||||
uint extractFace(ivec2 quad) {
|
||||
return quad.y&7;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#version 460 core
|
||||
layout(location = 0) in flat vec4 colour;
|
||||
layout(location = 0) out vec4 outColour;
|
||||
void main() {
|
||||
//TODO: randomly discard the fragment with respect to the alpha value
|
||||
|
||||
outColour = colour;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#version 460 core
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
#import <voxelmon:lod/gl46/quad_format.glsl>
|
||||
#import <voxelmon:lod/gl46/bindings.glsl>
|
||||
|
||||
layout(location = 0) out flat vec4 colour;
|
||||
|
||||
uint extractLodLevel() {
|
||||
return uint(gl_BaseInstance)>>29;
|
||||
}
|
||||
|
||||
//Note the last 2 bits of gl_BaseInstance are unused
|
||||
//Gives a relative position of +-255 relative to the player center in its respective lod
|
||||
ivec3 extractRelativeLodPos() {
|
||||
return (ivec3(gl_BaseInstance)<<ivec3(3,12,21))>>ivec3(23);
|
||||
}
|
||||
|
||||
vec4 uint2vec4RGBA(uint colour) {
|
||||
return vec4((uvec4(colour)>>uvec4(24,16,8,0))&uvec4(0xFF))/255;
|
||||
}
|
||||
|
||||
void main() {
|
||||
int cornerIdx = gl_VertexID&3;
|
||||
|
||||
Quad quad = quadData[uint(gl_VertexID)>>2];
|
||||
vec3 innerPos = extractPos(quad);
|
||||
|
||||
uint face = extractFace(quad);
|
||||
|
||||
uint lodLevel = extractLodLevel();
|
||||
ivec3 lodCorner = ((extractRelativeLodPos()<<lodLevel) - (baseSectionPos&(ivec3((1<<lodLevel)-1))))<<5;
|
||||
vec3 corner = innerPos * (1<<lodLevel) + lodCorner;
|
||||
|
||||
//TODO: see if backface culling is even needed, since everything (should) be back culled already
|
||||
//Flip the quad rotation by its face (backface culling)
|
||||
if ((face&1) != 0) {
|
||||
cornerIdx ^= 1;
|
||||
}
|
||||
if ((face>>1) == 0) {
|
||||
cornerIdx ^= 1;
|
||||
}
|
||||
|
||||
ivec2 size = extractSize(quad) * ivec2((cornerIdx>>1)&1, cornerIdx&1) * (1<<lodLevel);
|
||||
|
||||
vec3 pos = corner;
|
||||
|
||||
//NOTE: can just make instead of face, make it axis (can also make it 2 bit instead of 3 bit then)
|
||||
// since the only reason face is needed is to ensure backface culling orientation thing
|
||||
uint axis = face>>1;
|
||||
if (axis == 0) {
|
||||
pos.xz += size;
|
||||
pos.y += (face&1)<<lodLevel;
|
||||
} else if (axis == 1) {
|
||||
pos.xy += size;
|
||||
pos.z += (face&1)<<lodLevel;
|
||||
} else {
|
||||
pos.yz += size;
|
||||
pos.x += (face&1)<<lodLevel;
|
||||
}
|
||||
|
||||
gl_Position = MVP * vec4(pos,1);
|
||||
|
||||
uint stateId = extractStateId(quad);
|
||||
uint biomeId = extractBiomeId(quad);
|
||||
State stateInfo = stateData[stateId];
|
||||
colour = uint2vec4RGBA(stateInfo.faceColours[face]);
|
||||
if (((stateInfo.biomeTintMsk>>face)&1) == 1) {
|
||||
vec4 biomeColour = uint2vec4RGBA(biomeData[biomeId].foliage);
|
||||
colour *= biomeColour;
|
||||
}
|
||||
//Apply water tint
|
||||
if (((stateInfo.biomeTintMsk>>6)&1) == 1) {
|
||||
colour *= vec4(0.247, 0.463, 0.894, 1);
|
||||
}
|
||||
//gl_Position = MVP * vec4(vec3(((cornerIdx)&1)+10,10,((cornerIdx>>1)&1)+10),1);
|
||||
//uint i = uint(quad>>32);
|
||||
uint i = uint(gl_BaseInstance);
|
||||
i ^= i>>16;
|
||||
i *= 124128573;
|
||||
i ^= i>>16;
|
||||
i *= 4211346123;
|
||||
i ^= i>>16;
|
||||
i *= 462312435;
|
||||
i ^= i>>16;
|
||||
i *= 542354341;
|
||||
i ^= i>>16;
|
||||
|
||||
//uint i = uint(lodLevel+12)*215387625;
|
||||
//colour *= vec4(vec3(float((uint(i)>>2)&7)/7,float((uint(i)>>5)&7)/7,float((uint(i)>>8)&7)/7)*0.7+0.3,1);
|
||||
//colour = vec4(vec3(float((uint(i)>>2)&7)/7,float((uint(i)>>5)&7)/7,float((uint(i)>>8)&7)/7),1);
|
||||
}
|
||||
Reference in New Issue
Block a user