diff --git a/src/main/java/me/cortex/zenith/client/core/VoxelCore.java b/src/main/java/me/cortex/zenith/client/core/VoxelCore.java index 0d85d1e0..f5fef648 100644 --- a/src/main/java/me/cortex/zenith/client/core/VoxelCore.java +++ b/src/main/java/me/cortex/zenith/client/core/VoxelCore.java @@ -100,7 +100,7 @@ public class VoxelCore { //this.distanceTracker.init(camera.getBlockPos().getX(), camera.getBlockPos().getZ()); this.firstTime = false; - this.renderTracker.addLvl0(0,0,0); + this.renderTracker.addLvl0(0,6,0); } diff --git a/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java b/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java index 8356bc34..e122f701 100644 --- a/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java +++ b/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java @@ -100,9 +100,9 @@ public class ModelManager { //TODO: so need a few things, per face sizes and offsets, the sizes should be computed from the pixels and find the minimum bounding pixel // while the depth is computed from the depth buffer data public int addEntry(int blockId, BlockState blockState) { - //if (this.idMappings[blockId] != -1) { - // throw new IllegalArgumentException("Trying to add entry for duplicate id"); - //} + if (this.idMappings[blockId] != -1) { + throw new IllegalArgumentException("Trying to add entry for duplicate id"); + } int modelId = -1; var textureData = this.bakery.renderFaces(blockState, 123456); @@ -111,7 +111,7 @@ public class ModelManager { if (possibleDuplicate != -1) {//Duplicate found this.idMappings[blockId] = possibleDuplicate; modelId = possibleDuplicate; - //return possibleDuplicate; + return possibleDuplicate; } else {//Not a duplicate so create a new entry modelId = this.modelTexture2id.size(); this.idMappings[blockId] = modelId; @@ -163,6 +163,16 @@ public class ModelManager { //TODO: implement boolean hasBiomeColourResolver = false; + + //TODO: THIS, note this can be tested for in 2 ways, re render the model with quad culling disabled and see if the result + // is the same, (if yes then needs double sided quads) + // another way to test it is if e.g. up and down havent got anything rendered but the sides do (e.g. all plants etc) + boolean needsDoubleSidedQuads = false; + + //TODO: special case stuff like vines and glow lichen, where it can be represented by a single double sided quad + // since that would help alot with perf of lots of vines + + //This also checks if there is a block colour resolver for the given blockstate and marks that the block has a resolver var sizes = this.computeModelDepth(textureData, checkMode); @@ -209,10 +219,10 @@ public class ModelManager { int faceModelData = 0; faceModelData |= faceSize[0] | (faceSize[1]<<4) | (faceSize[2]<<8) | (faceSize[3]<<12); - faceModelData |= Math.round(offset*63);//Change the scale from 0->1 (ends inclusive) float to 0->63 (6 bits) NOTE! that 63 == 1.0f meaning its shifted all the way to the other side of the model + faceModelData |= Math.round(offset*63)<<16;//Change the scale from 0->1 (ends inclusive) float to 0->63 (6 bits) NOTE! that 63 == 1.0f meaning its shifted all the way to the other side of the model //Still have 11 bits free - MemoryUtil.memPutInt(faceUploadPtr, faceModelData); + MemoryUtil.memPutInt(faceUploadPtr, 0); } this.metadataCache[modelId] = metadata; diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java b/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java index ecfdbd00..cd7307e4 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java @@ -150,8 +150,8 @@ public class GeometryManager { MemoryUtil.memPutInt(ptr, (int) this.aabb); ptr += 4; ptr += 4; + MemoryUtil.memPutInt(ptr, this.opaqueGeometryPtr); ptr += 4; MemoryUtil.memPutInt(ptr, this.count); ptr += 4; - //MemoryUtil.memPutInt(ptr, this.opaqueQuadCount); ptr += 4; //MemoryUtil.memPutInt(ptr, (int) this.translucentGeometryPtr + this.translucentPreDataCount); ptr += 4; //MemoryUtil.memPutInt(ptr, this.translucentQuadCount); ptr += 4; @@ -163,7 +163,7 @@ public class GeometryManager { //TODO: support translucent geometry //return new SectionMeta(geometry.position, 0, geometryPtr, (int) (geometry.opaque.buffer().size/8), 0, -1,0, 0); - return new SectionMeta(geometry.position, 0, geometryPtr, (int) (geometry.opaque.buffer().size/8), 0); + return new SectionMeta(geometry.position, 0, geometryPtr, (int) (geometry.opaque.buffer().size/8), -1); } private void freeMeta(SectionMeta meta) { diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/Gl46FarWorldRenderer.java b/src/main/java/me/cortex/zenith/client/core/rendering/Gl46FarWorldRenderer.java index 85de7dc8..4822d8cd 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/Gl46FarWorldRenderer.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/Gl46FarWorldRenderer.java @@ -107,12 +107,14 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT); this.lodShader.bind(); + glDisable(GL_CULL_FACE); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, this.geometry.getSectionCount(), 0); + glEnable(GL_CULL_FACE); //ARBIndirectParameters.glMultiDrawElementsIndirectCountARB( glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT); - cullShader.bind(); + this.cullShader.bind(); glColorMask(false, false, false, false); glDepthMask(false); diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java b/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java index 78a66133..844afead 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java @@ -34,8 +34,20 @@ public class RenderDataFactory { // this stops e.g. multiple layers of glass (and ocean) from having 3000 layers of quads etc var buff = new MemoryBuffer(8*1); + //MemoryUtil.memPutLong(buff.address, encodeRaw(1, 0,2,0,0,0,515,0, 0));//92 + //MemoryUtil.memPutLong(buff.address+8, encodeRaw(2, 1,1,0,0,0,515,0, 0));//92 + //MemoryUtil.memPutLong(buff.address+16, encodeRaw(3, 0,0,0,0,0,515,0, 0));//92 + //MemoryUtil.memPutLong(buff.address+24, encodeRaw(4, 0,2,0,0,0,515,0, 0));//92 + //MemoryUtil.memPutLong(buff.address+32, encodeRaw(5, 0,2,0,0,0,515,0, 0));//92 + MemoryUtil.memPutLong(buff.address, encodeRaw(2, 1,1,0,0,0,515,0, 0));//92 + //MemoryUtil.memPutLong(buff.address, encodeRaw(3, 0,0,0,0,0,515,0, 0));//92 return new BuiltSection(section.getKey(), new BuiltSectionGeometry(buff, new short[0]), null); } + + private static long encodeRaw(int face, int width, int height, int x, int y, int z, int blockId, int biomeId, int lightId) { + return ((long)face) | (((long) width)<<3) | (((long) height)<<7) | (((long) z)<<11) | (((long) y)<<16) | (((long) x)<<21) | (((long) blockId)<<26) | (((long) biomeId)<<46) | (((long) lightId)<<55); + } + } diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl b/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl index 1a8f01b6..b52fba54 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl @@ -12,12 +12,17 @@ layout(binding = 0, std140) uniform SceneUniform { }; struct BlockModel { - uint faceColours[6]; + uint faceData[6]; + uint _pad[10]; }; struct SectionMeta { - uvec4 header; - uvec4 drawdata; + uint posA; + uint posB; + uint AABB; + uint _padA; + uint ptr; + uint cnt; }; //TODO: see if making the stride 2*4*4 bytes or something cause you get that 16 byte write diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/block_model.glsl b/src/main/resources/assets/zenith/shaders/lod/gl46/block_model.glsl new file mode 100644 index 00000000..0c2588c7 --- /dev/null +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/block_model.glsl @@ -0,0 +1,9 @@ +//TODO: FIXME: this isnt actually correct cause depending on the face (i think) it could be 1/64 th of a position off +// but im going to assume that since we are dealing with huge render distances, this shouldent matter that much +float extractFaceIndentation(uint faceData) { + return float((faceData>>16)&63)/63; +} + +vec4 extractFaceSizes(uint faceData) { + return (vec4(faceData&0xF, (faceData>>4)&0xF, (faceData>>8)&0xF, (faceData>>12)&0xF)/16)+vec4(0,1f/16,0,1f/16); +} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/quad_format.glsl b/src/main/resources/assets/zenith/shaders/lod/gl46/quad_format.glsl index 2867eaba..51978518 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/quad_format.glsl +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/quad_format.glsl @@ -17,7 +17,7 @@ uint extractFace(uint64_t quad) { } uint extractStateId(uint64_t quad) { - return Eu32(quad, 20, 26); + return Eu32(quad, 16, 26); } uint extractBiomeId(uint64_t quad) { diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/quads.frag b/src/main/resources/assets/zenith/shaders/lod/gl46/quads.frag index a2a4f69c..f1e2c3db 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/quads.frag +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/quads.frag @@ -4,10 +4,14 @@ layout(binding = 0) uniform sampler2D blockModelAtlas; layout(location = 0) in vec2 uv; layout(location = 1) in flat vec2 baseUV; layout(location = 2) in flat vec4 colourTinting; +layout(location = 3) in flat int discardAlpha; layout(location = 0) out vec4 outColour; void main() { vec2 uv = mod(uv, vec2(1))*(1f/(vec2(3,2)*256f)); - - outColour = texture(blockModelAtlas, uv + baseUV) * colourTinting; + vec4 colour = texture(blockModelAtlas, uv + baseUV); + if (discardAlpha == 1 && colour.a == 0.0f) { + discard; + } + outColour = colour * colourTinting; } \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/quads.vert b/src/main/resources/assets/zenith/shaders/lod/gl46/quads.vert index f71f3a0d..b855e4ac 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/quads.vert +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/quads.vert @@ -3,10 +3,13 @@ #import #import +#import +#line 8 layout(location = 0) out vec2 uv; layout(location = 1) out flat vec2 baseUV; layout(location = 2) out flat vec4 colourTinting; +layout(location = 3) out flat int discardAlpha; uint extractLodLevel() { return uint(gl_BaseInstance)>>29; @@ -22,59 +25,69 @@ vec4 uint2vec4RGBA(uint colour) { return vec4((uvec4(colour)>>uvec4(24,16,8,0))&uvec4(0xFF))/255; } +//Gets the face offset with respect to the face direction (e.g. some will be + some will be -) +float getFaceOffset(BlockModel model, uint face) { + float offset = extractFaceIndentation(model.faceData[face]); + return offset * (1-((int(face)&1)*2)); +} + +vec2 getFaceSizeOffset(BlockModel model, uint face, uint corner) { + vec4 faceOffsetsSizes = extractFaceSizes(model.faceData[face]); + return mix(faceOffsetsSizes.xz, -(1-faceOffsetsSizes.yw), bvec2(((corner>>1)&1)==1, (corner&1)==1)); +} + +//TODO: add a mechanism so that some quads can ignore backface culling +// this would help alot with stuff like crops as they would look kinda weird i think, +// same with flowers etc void main() { int cornerIdx = gl_VertexID&3; - Quad quad = quadData[uint(gl_VertexID)>>2]; vec3 innerPos = extractPos(quad); - uint face = extractFace(quad); + uint modelId = extractStateId(quad); + BlockModel model = modelData[modelId]; + + //Change the ordering due to backface culling + //NOTE: when rendering, backface culling is disabled as we simply dispatch calls for each face + // this has the advantage of having "unassigned" geometry, that is geometry where the backface isnt culled + //if (face == 0 || (face>>1 != 0 && (face&1)==1)) { + // cornerIdx ^= 1; + //} uint lodLevel = extractLodLevel(); ivec3 lodCorner = ((extractRelativeLodPos()<>1)&1, cornerIdx&1)); + vec2 size = (quadSize + faceOffset) * (1<>1) == 0) {//Up/down + offset = offset.xzy; } - if ((face>>1) == 0) { - cornerIdx ^= 1; + //Not needed, here for readability + //if ((face>>1) == 1) {//north/south + // offset = offset.xyz; + //} + if ((face>>1) == 2) {//west/east + offset = offset.zxy; } - ivec2 sizePreLod = extractSize(quad) * ivec2((cornerIdx>>1)&1, cornerIdx&1); - ivec2 size = sizePreLod * (1<>1; - if (axis == 0) { - pos.xz += size; - pos.y += (face&1)<>8)&0xFF)*(1f/(256f)); + //Compute the uv coordinates + vec2 modelUV = vec2(modelId&0xFF, (modelId>>8)&0xFF)*(1f/(256f)); //TODO: make the face orientated by 2x3 so that division is not a integer div and modulo isnt needed // as these are very slow ops baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3,2)*256f))); + uv = quadSize + faceOffset;//Add in the face offset for 0,0 uv + discardAlpha = 0; + + //Compute lighting colourTinting = getLighting(extractLightId(quad)); //Apply face tint if (face == 0) { @@ -82,21 +95,4 @@ void main() { } else if (face != 1) { colourTinting.xyz *= vec3((float(face-2)/4)*0.6 + 0.4); } - -} -//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); \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/section.glsl b/src/main/resources/assets/zenith/shaders/lod/gl46/section.glsl index 3a1842b7..5aab92a5 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/section.glsl +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/section.glsl @@ -1,21 +1,21 @@ uint extractDetail(SectionMeta section) { - return section.header.x>>28; + return section.posA>>28; } 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); + int y = ((int(section.posA)<<4)>>24); + int x = (int(section.posB)<<4)>>8; + int z = int((section.posA&((1<<20)-1))<<4); + z |= int(section.posB>>28); z <<= 8; z >>= 8; return ivec3(x,y,z); } uint extractQuadStart(SectionMeta meta) { - return meta.drawdata.x; + return meta.ptr; } uint extractQuadCount(SectionMeta meta) { - return meta.drawdata.y; + return meta.cnt; }