diff --git a/src/main/java/me/cortex/zenith/client/core/DistanceTracker.java b/src/main/java/me/cortex/zenith/client/core/DistanceTracker.java index 951bba63..9d1dad9e 100644 --- a/src/main/java/me/cortex/zenith/client/core/DistanceTracker.java +++ b/src/main/java/me/cortex/zenith/client/core/DistanceTracker.java @@ -28,8 +28,9 @@ public class DistanceTracker { this.minYSection = MinecraftClient.getInstance().world.getBottomSectionCoord()/2; this.maxYSection = MinecraftClient.getInstance().world.getTopSectionCoord()/2; - if (true) { - this.rings[0] = new TransitionRing2D(5, MinecraftClient.getInstance().options.getViewDistance().getValue() / 2, (x, z) -> { + int radius = (MinecraftClient.getInstance().options.getViewDistance().getValue() / 2) - 4; + if (radius > 0 && false) { + this.rings[0] = new TransitionRing2D(5, radius, (x, z) -> { for (int y = this.minYSection; y <= this.maxYSection; y++) { this.tracker.remLvl0(x, y, z); } 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 28a6535f..db995986 100644 --- a/src/main/java/me/cortex/zenith/client/core/VoxelCore.java +++ b/src/main/java/me/cortex/zenith/client/core/VoxelCore.java @@ -1,14 +1,15 @@ package me.cortex.zenith.client.core; +import com.mojang.blaze3d.platform.GlStateManager; import me.cortex.zenith.client.config.ZenithConfig; import me.cortex.zenith.client.core.rendering.*; import me.cortex.zenith.client.core.rendering.building.RenderGenerationService; +import me.cortex.zenith.client.core.rendering.post.PostProcessing; import me.cortex.zenith.client.core.util.DebugUtil; import me.cortex.zenith.common.world.WorldEngine; import me.cortex.zenith.client.importers.WorldImporter; import me.cortex.zenith.common.world.storage.FragmentedStorageBackendAdaptor; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; import net.minecraft.client.util.math.MatrixStack; @@ -63,7 +64,7 @@ public class VoxelCore { this.distanceTracker = new DistanceTracker(this.renderTracker, 5, ZenithConfig.CONFIG.qualityScale); System.out.println("Distance tracker initialized"); - this.postProcessing = null;//new PostProcessing(); + this.postProcessing = new PostProcessing(); this.world.getMapper().setCallbacks(this.renderer::addBlockState, a->{}); @@ -107,9 +108,8 @@ public class VoxelCore { //this.renderer.getModelManager().updateEntry(0, Blocks.COMPARATOR.getDefaultState()); //this.renderer.getModelManager().updateEntry(0, Blocks.OAK_LEAVES.getDefaultState()); - //int boundFB = GlStateManager.getBoundFramebuffer(); - //this.postProcessing.setSize(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight); - //this.postProcessing.bindClearFramebuffer(); + int boundFB = GlStateManager.getBoundFramebuffer(); + this.postProcessing.setup(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight, boundFB); //TODO: FIXME: since we just bound the post processing FB the depth information isnt // copied over, we must do this manually and also copy it with respect to the @@ -121,13 +121,15 @@ public class VoxelCore { // occlusion culler this.renderer.renderFarAwayOpaque(matrices, cameraX, cameraY, cameraZ); - - - //glBindFramebuffer(GL_FRAMEBUFFER, boundFB); - //this.postProcessing.renderPost(boundFB); + //Compute the SSAO of the rendered terrain + this.postProcessing.computeSSAO(); //We can render the translucent directly after as it is the furthest translucent objects this.renderer.renderFarAwayTranslucent(); + + + this.postProcessing.renderPost(boundFB); + } public void addDebugInfo(List debug) { diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/PostProcessing.java b/src/main/java/me/cortex/zenith/client/core/rendering/PostProcessing.java deleted file mode 100644 index 9a6bb73d..00000000 --- a/src/main/java/me/cortex/zenith/client/core/rendering/PostProcessing.java +++ /dev/null @@ -1,81 +0,0 @@ -package me.cortex.zenith.client.core.rendering; - -import me.cortex.zenith.client.core.gl.GlFramebuffer; -import me.cortex.zenith.client.core.gl.GlTexture; -import me.cortex.zenith.client.core.gl.shader.Shader; -import me.cortex.zenith.client.core.gl.shader.ShaderType; -import org.lwjgl.opengl.GL11C; - -import static org.lwjgl.opengl.ARBFramebufferObject.*; -import static org.lwjgl.opengl.ARBShaderImageLoadStore.glBindImageTexture; -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL13.*; -import static org.lwjgl.opengl.GL15C.GL_READ_WRITE; -import static org.lwjgl.opengl.GL44C.glBindImageTextures; -import static org.lwjgl.opengl.GL45C.glTextureBarrier; - -public class PostProcessing { - private final GlFramebuffer framebuffer; - private int width; - private int height; - private GlTexture colour; - private GlTexture depthStencil; - - private final Shader ssao = Shader.make() - .add(ShaderType.COMPUTE, "voxelmon:lod/ssao/ssao.comp") - .compile(); - - //private final Shader blit = Shader.make() - // .add(ShaderType.VERTEX, "voxelmon:lod/blit_nodepth/quad.vert") - // .add(ShaderType.FRAGMENT, "voxelmon:lod/blit_nodepth/quad.frag") - // .compile(); - - public PostProcessing() { - this.framebuffer = new GlFramebuffer(); - } - - public void setSize(int width, int height) { - if (this.width != width || this.height != height) { - this.width = width; - this.height = height; - if (this.colour != null) { - this.colour.free(); - this.depthStencil.free(); - } - - this.colour = new GlTexture().store(GL_RGBA8, 1, width, height); - this.depthStencil = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width, height); - - this.framebuffer.bind(GL_COLOR_ATTACHMENT0, this.colour); - this.framebuffer.bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthStencil); - this.framebuffer.verify(); - } - } - - //Bind and clears the post processing frame buffer - public void bindClearFramebuffer() { - glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer.id); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } - - //Executes the post processing and emits to whatever framebuffer is currently bound via a blit - public void renderPost(int outputFb) { - this.ssao.bind(); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, this.depthStencil.id); - glBindImageTexture(0, this.colour.id, 0, false,0, GL_READ_WRITE, GL_RGBA8); - //glDispatchCompute(this.width/32, this.height/32, 1); - glTextureBarrier(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, this.colour.id); - glDrawArrays(GL11C.GL_TRIANGLES, 0, 3); - } - - public void shutdown() { - this.framebuffer.free(); - if (this.colour != null) this.colour.free(); - if (this.depthStencil != null) this.depthStencil.free(); - this.ssao.free(); - //this.blit.free(); - } -} diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/post/FullscreenBlit.java b/src/main/java/me/cortex/zenith/client/core/rendering/post/FullscreenBlit.java new file mode 100644 index 00000000..5b9b2264 --- /dev/null +++ b/src/main/java/me/cortex/zenith/client/core/rendering/post/FullscreenBlit.java @@ -0,0 +1,33 @@ +package me.cortex.zenith.client.core.rendering.post; + +import me.cortex.zenith.client.core.gl.shader.Shader; +import me.cortex.zenith.client.core.gl.shader.ShaderType; +import net.minecraft.util.Identifier; + +import static org.lwjgl.opengl.GL11C.GL_TRIANGLES; +import static org.lwjgl.opengl.GL11C.glDrawArrays; +import static org.lwjgl.opengl.GL30C.glBindVertexArray; +import static org.lwjgl.opengl.GL45C.glCreateVertexArrays; + +public class FullscreenBlit { + private static final int EMPTY_VAO = glCreateVertexArrays(); + + private final Shader shader; + public FullscreenBlit(String fragId) { + this.shader = Shader.make() + .add(ShaderType.VERTEX, "zenith:post/fullscreen.vert") + .add(ShaderType.FRAGMENT, fragId) + .compile(); + } + + public void blit() { + glBindVertexArray(EMPTY_VAO); + this.shader.bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } + + public void delete() { + this.shader.free(); + } +} diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/post/PostProcessing.java b/src/main/java/me/cortex/zenith/client/core/rendering/post/PostProcessing.java new file mode 100644 index 00000000..71485cba --- /dev/null +++ b/src/main/java/me/cortex/zenith/client/core/rendering/post/PostProcessing.java @@ -0,0 +1,147 @@ +package me.cortex.zenith.client.core.rendering.post; + +import me.cortex.zenith.client.core.gl.GlFramebuffer; +import me.cortex.zenith.client.core.gl.GlTexture; +import me.cortex.zenith.client.core.gl.shader.Shader; +import me.cortex.zenith.client.core.gl.shader.ShaderType; +import org.lwjgl.opengl.GL11C; + +import static org.lwjgl.opengl.ARBFramebufferObject.*; +import static org.lwjgl.opengl.ARBShaderImageLoadStore.glBindImageTexture; +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL13.*; +import static org.lwjgl.opengl.GL15C.GL_READ_WRITE; +import static org.lwjgl.opengl.GL20C.glStencilFuncSeparate; +import static org.lwjgl.opengl.GL44C.glBindImageTextures; +import static org.lwjgl.opengl.GL45C.glBlitNamedFramebuffer; +import static org.lwjgl.opengl.GL45C.glTextureBarrier; + +public class PostProcessing { + private final GlFramebuffer framebuffer; + private int width; + private int height; + private GlTexture colour; + private GlTexture depthStencil; + + private final Shader ssao = Shader.make() + .add(ShaderType.COMPUTE, "zenith:lod/ssao/ssao.comp") + .compile(); + + private final FullscreenBlit emptyBlit = new FullscreenBlit("zenith:post/noop.frag"); + private final FullscreenBlit blitTexture = new FullscreenBlit("zenith:post/blit_texture_cutout.frag"); + + public PostProcessing() { + this.framebuffer = new GlFramebuffer(); + } + + public void setSize(int width, int height) { + if (this.width != width || this.height != height) { + this.width = width; + this.height = height; + if (this.colour != null) { + this.colour.free(); + this.depthStencil.free(); + } + + this.colour = new GlTexture().store(GL_RGBA8, 1, width, height); + this.depthStencil = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width, height); + + this.framebuffer.bind(GL_COLOR_ATTACHMENT0, this.colour); + this.framebuffer.bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthStencil); + this.framebuffer.verify(); + } + } + + + + public void shutdown() { + this.framebuffer.free(); + if (this.colour != null) this.colour.free(); + if (this.depthStencil != null) this.depthStencil.free(); + this.ssao.free(); + this.emptyBlit.delete(); + this.blitTexture.delete(); + } + + public void setup(int width, int height, int sourceFB) { + this.setSize(width, height); + glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer.id); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glBlitNamedFramebuffer(sourceFB, this.framebuffer.id, 0,0, width, height, 0,0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + //TODO: need to blit a fullscreen quad to generate a stencil mask of where the vanilla terrain is/isnt + // then when rastering zenith terrain, only render to non masked areas + //Hell once the stencil mask is computed, could clear the depth buffer and use a different near/far plane + + + //Create a stencil mask of terrain generated by minecraft + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilMask(0xFF); + + glEnable(GL_DEPTH_TEST); + glDepthMask(false); + glColorMask(false,false,false,false); + this.emptyBlit.blit(); + glColorMask(true,true,true,true); + glDepthMask(true); + glDisable(GL_DEPTH_TEST); + + //Clear the depth buffer we copied cause else it will interfear with results (not really i think idk) + glClear(GL_DEPTH_BUFFER_BIT); + + + //Make zenith terrain render only where there isnt mc terrain + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 1, 0xFF); + + + //glDisable(GL_STENCIL_TEST); + + + //TODO: need to figure out how to do translucency cause doing it normally will cause water to have double translucency (i think) + } + + //Computes ssao on the current framebuffer data and updates it + // this means that translucency wont be effected etc + public void computeSSAO() { + + //this.ssao.bind(); + //glActiveTexture(GL_TEXTURE1); + //glBindTexture(GL_TEXTURE_2D, this.depthStencil.id); + //glBindImageTexture(0, this.colour.id, 0, false,0, GL_READ_WRITE, GL_RGBA8); + ////glDispatchCompute(this.width/32, this.height/32, 1); + //glTextureBarrier(); + //glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_2D, this.colour.id); + //glDrawArrays(GL11C.GL_TRIANGLES, 0, 3); + } + + + //Executes the post processing and emits to whatever framebuffer is currently bound via a blit + public void renderPost(int outputFB) { + glDisable(GL_STENCIL_TEST); + + + + glBindFramebuffer(GL_FRAMEBUFFER, outputFB); + + //This will need to be replaced with a blit shader to raster with respect to the stencil + //glBlitNamedFramebuffer(this.framebuffer.id, outputFB, 0,0, this.width, this.height, 0,0, this.width, this.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + + + int oldActiveTexture = glGetInteger(GL_ACTIVE_TEXTURE); + glActiveTexture(GL_TEXTURE0); + int oldBoundTexture = glGetInteger(GL_TEXTURE_BINDING_2D); + glBindTexture(GL_TEXTURE_2D, this.colour.id); + glEnable(GL_DEPTH_TEST); + glDepthMask(false); + this.blitTexture.blit(); + glDisable(GL_DEPTH_TEST); + glDepthMask(true); + glBindTexture(GL_TEXTURE_2D, oldBoundTexture); + glActiveTexture(oldActiveTexture); + } +} diff --git a/src/main/java/me/cortex/zenith/common/world/service/VoxelIngestService.java b/src/main/java/me/cortex/zenith/common/world/service/VoxelIngestService.java index 719b185c..124bb86d 100644 --- a/src/main/java/me/cortex/zenith/common/world/service/VoxelIngestService.java +++ b/src/main/java/me/cortex/zenith/common/world/service/VoxelIngestService.java @@ -55,11 +55,11 @@ public class VoxelIngestService { section.getBiomeContainer(), (x, y, z, state) -> { if (lighting == null || ((lighting.first() != null && lighting.first().isUninitialized())&&(lighting.second()!=null&&lighting.second().isUninitialized()))) { - return (byte) 0xFF; + return (byte) 0x0f; } else { //Lighting is a piece of shit cause its done per face - int block = lighting.first()!=null?Math.min(15,lighting.first().get(x, y, z)):0xF; - int sky = lighting.second()!=null?Math.min(15,lighting.second().get(x, y, z)):0xF; + int block = lighting.first()!=null?Math.min(15,lighting.first().get(x, y, z)):0; + int sky = lighting.second()!=null?Math.min(15,lighting.second().get(x, y, z)):0; if (block>1)&1) * 4 - 1, 0.99999999999f, 1); + UV = gl_Position.xy*0.5+0.5; +} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/post/noop.frag b/src/main/resources/assets/zenith/shaders/post/noop.frag new file mode 100644 index 00000000..ef9c8f0d --- /dev/null +++ b/src/main/resources/assets/zenith/shaders/post/noop.frag @@ -0,0 +1,6 @@ +#version 330 core +out vec4 colour; +in vec2 UV; +void main() { + colour = vec4(1,0,1,1); +} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/postprocess/ssao.comp b/src/main/resources/assets/zenith/shaders/post/ssao.comp similarity index 100% rename from src/main/resources/assets/zenith/shaders/postprocess/ssao.comp rename to src/main/resources/assets/zenith/shaders/post/ssao.comp diff --git a/src/main/resources/assets/zenith/shaders/quads.frag b/src/main/resources/assets/zenith/shaders/quads.frag deleted file mode 100644 index f5988f1b..00000000 --- a/src/main/resources/assets/zenith/shaders/quads.frag +++ /dev/null @@ -1,8 +0,0 @@ -#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; -} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/quads.vert b/src/main/resources/assets/zenith/shaders/quads.vert deleted file mode 100644 index 30494c14..00000000 --- a/src/main/resources/assets/zenith/shaders/quads.vert +++ /dev/null @@ -1,18 +0,0 @@ -#version 460 core - -layout(location = 0) out flat vec4 colour; -layout(binding = 0, std140) uniform SceneUniform { - mat4 MVP; - ivec3 baseSectionPos; - int _pad1; -}; - -void main() { - int cornerIdx = gl_VertexID&3; - - - - gl_Position = MVP * vec4(vec3(cornerIdx&1,((cornerIdx>>1)&1),0),1); - - colour = vec4(float((uint(gl_VertexID)>>2)&7)/7,float((uint(gl_VertexID)>>5)&7)/7,float((uint(gl_VertexID)>>8)&7)/7,1); -} \ No newline at end of file diff --git a/src/main/resources/assets/zenith/shaders/ray/ray.glsl b/src__/ray/ray.glsl similarity index 100% rename from src/main/resources/assets/zenith/shaders/ray/ray.glsl rename to src__/ray/ray.glsl diff --git a/src/main/resources/assets/zenith/shaders/ray/storage.glsl b/src__/ray/storage.glsl similarity index 100% rename from src/main/resources/assets/zenith/shaders/ray/storage.glsl rename to src__/ray/storage.glsl diff --git a/src/main/resources/assets/zenith/shaders/ray/tracer.glsl b/src__/ray/tracer.glsl similarity index 100% rename from src/main/resources/assets/zenith/shaders/ray/tracer.glsl rename to src__/ray/tracer.glsl