From 0b2284e2586bf1408c2b5c959a2a688ae48a6591 Mon Sep 17 00:00:00 2001 From: NULL511 Date: Sun, 10 Sep 2023 00:47:04 -0400 Subject: [PATCH 01/12] refactor abstract shader base class and ssao renderer --- .../core/render/renderer/SSAORenderer.java | 125 ++++++++ .../core/render/renderer/ScreenQuad.java | 94 ++++++ .../shaders/AbstractShaderRenderer.java | 98 +------ .../render/renderer/shaders/DarkShader.java | 46 ++- .../render/renderer/shaders/FogShader.java | 42 ++- .../renderer/shaders/SSAOApplyShader.java | 119 ++++++++ .../render/renderer/shaders/SSAORenderer.java | 277 ------------------ .../render/renderer/shaders/SSAOShader.java | 137 +++++++++ 8 files changed, 560 insertions(+), 378 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java new file mode 100644 index 000000000..a3e9f2c09 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java @@ -0,0 +1,125 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.core.render.renderer; + +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.render.glObject.GLState; +import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOApplyShader; +import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOShader; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import org.lwjgl.opengl.GL32; + +import java.nio.ByteBuffer; + +public class SSAORenderer +{ + public static SSAORenderer INSTANCE = new SSAORenderer(); + + private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + + + private boolean init = false; + + private int width = -1; + private int height = -1; + private int ssaoFramebuffer = -1; + + private int ssaoTexture = -1; + + + //=============// + // constructor // + //=============// + + private SSAORenderer() { } + + public void init() + { + if (this.init) return; + this.init = true; + + SSAOShader.INSTANCE.init(); + + SSAOApplyShader.INSTANCE.init(); + } + + private void createFramebuffer(int width, int height) + { + if (this.ssaoFramebuffer != -1) + { + GL32.glDeleteFramebuffers(this.ssaoFramebuffer); + this.ssaoFramebuffer = -1; + } + + if (this.ssaoTexture != -1) + { + GL32.glDeleteTextures(this.ssaoTexture); + this.ssaoTexture = -1; + } + + this.ssaoFramebuffer = GL32.glGenFramebuffers(); + GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); + + this.ssaoTexture = GL32.glGenTextures(); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); + GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null); + GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); + GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); + GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.ssaoTexture, 0); + } + + + //========// + // render // + //========// + + public void render(GLState primaryState, float partialTicks) + { + GLState state = new GLState(); + + this.init(); + + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + + if (this.width != width || this.height != height) + { + this.width = width; + this.height = height; + this.createFramebuffer(width, height); + } + + ScreenQuad.INSTANCE.bind(); + + SSAOShader.INSTANCE.render(partialTicks, ssaoFramebuffer); + + primaryState.RestoreFrameBuffer(); + + SSAOApplyShader.INSTANCE.render(partialTicks, ssaoTexture); + + state.restore(); + } + + public void free() + { + SSAOShader.INSTANCE.free(); + SSAOApplyShader.INSTANCE.free(); + } +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java new file mode 100644 index 000000000..774a3a289 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java @@ -0,0 +1,94 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.core.render.renderer; + +import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod; +import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; +import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute; +import org.lwjgl.opengl.GL32; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class ScreenQuad +{ + public static ScreenQuad INSTANCE = new ScreenQuad(); + + private static final float[] box_vertices = { + -1, -1, + 1, -1, + 1, 1, + -1, -1, + 1, 1, + -1, 1, + }; + + private GLVertexBuffer boxBuffer; + private VertexAttribute va; + private boolean init = false; + + + //=============// + // constructor // + //=============// + + private ScreenQuad() { } + + public void init() + { + if (this.init) return; + this.init = true; + + this.va = VertexAttribute.create(); + this.va.bind(); + + // Pos + this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false)); + this.va.completeAndCheck(Float.BYTES * 2); + + // Framebuffer + this.createBuffer(); + } + + public void bind() + { + this.init(); + + this.va.bind(); + this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId()); + } + + public void render() + { + GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); + } + + private void createBuffer() + { + ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES); + buffer.order(ByteOrder.nativeOrder()); + buffer.asFloatBuffer().put(box_vertices); + buffer.rewind(); + + this.boxBuffer = new GLVertexBuffer(false); + this.boxBuffer.bind(); + this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); + } +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java index 9dc1006a5..3f9155c1d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java @@ -19,116 +19,26 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; -import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL32; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; public abstract class AbstractShaderRenderer { - protected static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final float[] box_vertices = { - -1, -1, - 1, -1, - 1, 1, - -1, -1, - 1, 1, - -1, 1, - }; - protected final ShaderProgram shader; - public GLVertexBuffer boxBuffer; - protected VertexAttribute va; + protected ShaderProgram shader; + boolean init = false; - protected AbstractShaderRenderer(ShaderProgram shader) - { - this.shader = shader; - } + protected AbstractShaderRenderer() {} - private void init() + public void init() { if (init) return; init = true; - - va = VertexAttribute.create(); - va.bind(); - - // Pos - setVertexAttributes(); - va.completeAndCheck(Float.BYTES * 2); - - // Some shader stuff needs to be set a bit later than - this.postInit(); - - // Framebuffer - this.createBuffer(); - } - - /** Sets all the vertex attributes */ - void setVertexAttributes() - { - va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false)); - } - - /** Overwrite this to apply uniforms to the shader */ - void setShaderUniforms(float partialTicks) { } - - /** Overwrite if you need to run something on runtime */ - void postInit() { } - - - // TODO pass in the Model View and Projection Matrices along with the ticks - public void render(float partialTicks) - { - GLState state = new GLState(); - this.init(); - - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - - GL32.glViewport(0, 0, width, height); - GL32.glDisable(GL32.GL_DEPTH_TEST); - GL32.glDisable(GL32.GL_SCISSOR_TEST); - - shader.bind(); - this.setShaderUniforms(partialTicks); - - va.bind(); - va.bindBufferToAllBindingPoint(boxBuffer.getId()); - - GL32.glActiveTexture(GL32.GL_TEXTURE0); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - - GL32.glEnable(GL11.GL_BLEND); - GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); - - state.restore(); - } - - private void createBuffer() - { - ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES); - buffer.order(ByteOrder.nativeOrder()); - buffer.asFloatBuffer().put(box_vertices); - buffer.rewind(); - - this.boxBuffer = new GLVertexBuffer(false); - this.boxBuffer.bind(); - this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); } public void free() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java index b0eab9b78..1028942ea 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java @@ -19,15 +19,57 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; +import com.seibel.distanthorizons.core.render.glObject.GLState; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; +import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; +import org.lwjgl.opengl.GL32; public class DarkShader extends AbstractShaderRenderer { public static DarkShader INSTANCE = new DarkShader(); + - protected DarkShader() + @Override + public void init() { - super(new ShaderProgram("shaders/normal.vert", "shaders/test/dark.frag", "fragColor", new String[]{"vPosition", "color"})); + super.init(); + + this.shader = new ShaderProgram( + "shaders/normal.vert", + "shaders/test/dark.frag", + "fragColor", + new String[]{"vPosition", "color"}); } + void setShaderUniforms() + { + GL32.glActiveTexture(GL32.GL_TEXTURE0); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); + } + + public void render() + { + GLState state = new GLState(); + + this.init(); + + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + + GL32.glViewport(0, 0, width, height); + GL32.glDisable(GL32.GL_DEPTH_TEST); + GL32.glDisable(GL32.GL_SCISSOR_TEST); + + shader.bind(); + + this.setShaderUniforms(); + + ScreenQuad.INSTANCE.bind(); + + GL32.glEnable(GL32.GL_BLEND); + GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); + ScreenQuad.INSTANCE.render(); + + state.restore(); + } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index efbc1f368..7349271d8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -23,11 +23,14 @@ import com.seibel.distanthorizons.api.enums.rendering.EFogColorMode; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.fog.LodFogConfig; +import com.seibel.distanthorizons.core.render.glObject.GLState; import com.seibel.distanthorizons.core.render.glObject.shader.Shader; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; +import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.coreapi.util.math.Mat4f; import org.lwjgl.opengl.GL32; @@ -36,6 +39,8 @@ import java.awt.*; public class FogShader extends AbstractShaderRenderer { public static FogShader INSTANCE = new FogShader(LodFogConfig.generateFogConfig()); + + private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class); @@ -51,15 +56,14 @@ public class FogShader extends AbstractShaderRenderer public final int fullFogModeUniform; - public FogShader(LodFogConfig fogConfig) { - super(new ShaderProgram( + this.shader = new ShaderProgram( // TODO rename normal.vert to something like "postProcess.vert" () -> Shader.loadFile("shaders/normal.vert", false, new StringBuilder()).toString(), () -> fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(), "fragColor", new String[]{"vPosition"} - )); + ); // all uniforms should be tryGet... // because disabling fog can cause the GLSL to optimize out most (if not all) uniforms @@ -78,7 +82,7 @@ public class FogShader extends AbstractShaderRenderer this.nearFogLengthUniform = this.shader.tryGetUniformLocation("nearFogLength"); } - @Override + //@Override void setShaderUniforms(float partialTicks) { this.shader.bind(); @@ -135,4 +139,32 @@ public class FogShader extends AbstractShaderRenderer this.shader.unbind(); } -} + + public void render(float partialTicks) + { + GLState state = new GLState(); + + this.init(); + + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + + GL32.glViewport(0, 0, width, height); + GL32.glDisable(GL32.GL_DEPTH_TEST); + GL32.glDisable(GL32.GL_SCISSOR_TEST); + + shader.bind(); + + this.setShaderUniforms(partialTicks); + + ScreenQuad.INSTANCE.bind(); + + GL32.glActiveTexture(GL32.GL_TEXTURE0); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); + + GL32.glEnable(GL32.GL_BLEND); + GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); + ScreenQuad.INSTANCE.render(); + + state.restore(); + }} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java new file mode 100644 index 000000000..fb85a4bb5 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -0,0 +1,119 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.core.render.renderer.shaders; + +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; +import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; +import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.RenderUtil; +import org.lwjgl.opengl.GL32; + +public class SSAOApplyShader extends AbstractShaderRenderer +{ + public static SSAOApplyShader INSTANCE = new SSAOApplyShader(); + + + // apply uniforms + private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms(); + + private static class ApplyShaderUniforms + { + public int gSSAOMapUniform; + public int gDepthMapUniform; + public int gViewSizeUniform; + public int gBlurRadiusUniform; + public int gNearUniform; + public int gFarUniform; + } + + + @Override + public void init() + { + super.init(); + + this.shader = new ShaderProgram( + "shaders/normal.vert", + "shaders/ssao/apply.frag", + "fragColor", + new String[]{"vPosition"}); + + // uniform setup + this.applyShaderUniforms.gSSAOMapUniform = this.shader.getUniformLocation("gSSAOMap"); + this.applyShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); + this.applyShaderUniforms.gViewSizeUniform = this.shader.tryGetUniformLocation("gViewSize"); + this.applyShaderUniforms.gBlurRadiusUniform = this.shader.tryGetUniformLocation("gBlurRadius"); + this.applyShaderUniforms.gNearUniform = this.shader.tryGetUniformLocation("gNear"); + this.applyShaderUniforms.gFarUniform = this.shader.tryGetUniformLocation("gFar"); + } + + private void setShaderUniforms(float partialTicks, int ssaoTexture) + { + GL32.glActiveTexture(GL32.GL_TEXTURE0); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); + GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0); + + GL32.glActiveTexture(GL32.GL_TEXTURE1); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, ssaoTexture); + GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1); + + int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get(); + GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius); + + if (this.applyShaderUniforms.gViewSizeUniform >= 0) + { + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height); + } + + if (this.applyShaderUniforms.gNearUniform >= 0) + { + float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); + GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, near); + } + + if (this.applyShaderUniforms.gFarUniform >= 0) + { + float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)); + GL32.glUniform1f(this.applyShaderUniforms.gFarUniform, far); + } + } + + //========// + // render // + //========// + + public void render(float partialTicks, int ssaoTexture) + { + this.init(); + + this.shader.bind(); + + setShaderUniforms(partialTicks, ssaoTexture); + + GL32.glEnable(GL32.GL_BLEND); + GL32.glBlendEquation(GL32.GL_FUNC_ADD); + GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE); + + ScreenQuad.INSTANCE.render(); + } +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java deleted file mode 100644 index c7eec888a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL v3 License. - * - * Copyright (C) 2020-2023 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.seibel.distanthorizons.core.render.renderer.shaders; - -import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.coreapi.util.math.Mat4f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL32; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class SSAORenderer -{ - public static SSAORenderer INSTANCE = new SSAORenderer(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - private static final float[] box_vertices = { - -1, -1, - 1, -1, - 1, 1, - -1, -1, - 1, 1, - -1, 1, - }; - - - private ShaderProgram ssaoShader; - private ShaderProgram applyShader; - - private GLVertexBuffer boxBuffer; - private VertexAttribute va; - private boolean init = false; - - private int width = -1; - private int height = -1; - private int ssaoFramebuffer = -1; - - private int ssaoTexture = -1; - - // ssao uniforms - private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms(); - private static class SsaoShaderUniforms - { - public int gProjUniform; - public int gInvProjUniform; - public int gSampleCountUniform; - public int gRadiusUniform; - public int gStrengthUniform; - public int gMinLightUniform; - public int gBiasUniform; - public int gDepthMapUniform; - } - - // apply uniforms - private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms(); - private static class ApplyShaderUniforms - { - public int gSSAOMapUniform; - public int gDepthMapUniform; - public int gViewSizeUniform; - public int gBlurRadiusUniform; - public int gNearUniform; - public int gFarUniform; - } - - - //=============// - // constructor // - //=============// - - private SSAORenderer() { } - - public void init() - { - if (this.init) return; - this.init = true; - - this.va = VertexAttribute.create(); - this.va.bind(); - - // Pos - this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false)); - this.va.completeAndCheck(Float.BYTES * 2); - this.ssaoShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag", - "fragColor", new String[]{"vPosition"}); - - this.applyShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/apply.frag", - "fragColor", new String[]{"vPosition"}); - - // SSAO uniform setup - this.ssaoShaderUniforms.gProjUniform = this.ssaoShader.getUniformLocation("gProj"); - this.ssaoShaderUniforms.gInvProjUniform = this.ssaoShader.getUniformLocation("gInvProj"); - this.ssaoShaderUniforms.gSampleCountUniform = this.ssaoShader.getUniformLocation("gSampleCount"); - this.ssaoShaderUniforms.gRadiusUniform = this.ssaoShader.getUniformLocation("gRadius"); - this.ssaoShaderUniforms.gStrengthUniform = this.ssaoShader.getUniformLocation("gStrength"); - this.ssaoShaderUniforms.gMinLightUniform = this.ssaoShader.getUniformLocation("gMinLight"); - this.ssaoShaderUniforms.gBiasUniform = this.ssaoShader.getUniformLocation("gBias"); - this.ssaoShaderUniforms.gDepthMapUniform = this.ssaoShader.getUniformLocation("gDepthMap"); - - // Apply uniform setup - this.applyShaderUniforms.gSSAOMapUniform = this.applyShader.getUniformLocation("gSSAOMap"); - this.applyShaderUniforms.gDepthMapUniform = this.applyShader.getUniformLocation("gDepthMap"); - this.applyShaderUniforms.gViewSizeUniform = this.applyShader.tryGetUniformLocation("gViewSize"); - this.applyShaderUniforms.gBlurRadiusUniform = this.applyShader.tryGetUniformLocation("gBlurRadius"); - this.applyShaderUniforms.gNearUniform = this.applyShader.tryGetUniformLocation("gNear"); - this.applyShaderUniforms.gFarUniform = this.applyShader.tryGetUniformLocation("gFar"); - - // Framebuffer - this.createBuffer(); - } - - private void createFramebuffer(int width, int height) - { - if (this.ssaoFramebuffer != -1) - { - GL32.glDeleteFramebuffers(this.ssaoFramebuffer); - this.ssaoFramebuffer = -1; - } - - if (this.ssaoTexture != -1) - { - GL32.glDeleteTextures(this.ssaoTexture); - this.ssaoTexture = -1; - } - - this.ssaoFramebuffer = GL32.glGenFramebuffers(); - GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); - - this.ssaoTexture = GL32.glGenTextures(); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.ssaoTexture, 0); - } - - private void createBuffer() - { - ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES); - buffer.order(ByteOrder.nativeOrder()); - buffer.asFloatBuffer().put(box_vertices); - buffer.rewind(); - - this.boxBuffer = new GLVertexBuffer(false); - this.boxBuffer.bind(); - this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); - } - - - //========// - // render // - //========// - - public void render(GLState primaryState, float partialTicks) - { - GLState state = new GLState(); - - this.init(); - - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - - if (this.width != width || this.height != height) - { - this.width = width; - this.height = height; - this.createFramebuffer(width, height); - } - - GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); - GL32.glViewport(0, 0, width, height); - GL32.glDisable(GL32.GL_SCISSOR_TEST); - GL32.glDisable(GL32.GL_DEPTH_TEST); - GL32.glDisable(GL11.GL_BLEND); - - float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); - float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)); - - Mat4f perspective = Mat4f.perspective( - (float) MC_RENDER.getFov(partialTicks), - width / (float) height, - near, far); - - Mat4f invertedPerspective = new Mat4f(perspective); - invertedPerspective.invert(); - - int sampleCount = Config.Client.Advanced.Graphics.Ssao.sampleCount.get(); - int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get(); - float radius = Config.Client.Advanced.Graphics.Ssao.radius.get().floatValue(); - float strength = Config.Client.Advanced.Graphics.Ssao.strength.get().floatValue(); - float minLight = Config.Client.Advanced.Graphics.Ssao.minLight.get().floatValue(); - float bias = Config.Client.Advanced.Graphics.Ssao.bias.get().floatValue(); - - this.ssaoShader.bind(); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gProjUniform, perspective); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gInvProjUniform, invertedPerspective); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gSampleCountUniform, sampleCount); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gRadiusUniform, radius); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gStrengthUniform, strength); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gMinLightUniform, minLight); - this.ssaoShader.setUniform(this.ssaoShaderUniforms.gBiasUniform, bias); - - this.va.bind(); - this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId()); - - GL32.glActiveTexture(GL32.GL_TEXTURE0); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - - GL32.glUniform1i(this.ssaoShaderUniforms.gDepthMapUniform, 0); - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); - - this.applyShader.bind(); - - primaryState.RestoreFrameBuffer(); - - GL32.glEnable(GL11.GL_BLEND); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE); - - GL32.glActiveTexture(GL32.GL_TEXTURE0); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0); - - GL32.glActiveTexture(GL32.GL_TEXTURE1); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); - GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1); - - GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius); - - if (this.applyShaderUniforms.gViewSizeUniform >= 0) - GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height); - - if (this.applyShaderUniforms.gNearUniform >= 0) - GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, near); - - if (this.applyShaderUniforms.gFarUniform >= 0) - GL32.glUniform1f(this.applyShaderUniforms.gFarUniform, far); - - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); - - state.restore(); - } - - public void free() - { - this.ssaoShader.free(); - this.applyShader.free(); - } -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java new file mode 100644 index 000000000..9fe7e2fbe --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -0,0 +1,137 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.core.render.renderer.shaders; + +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; +import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; +import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.RenderUtil; +import com.seibel.distanthorizons.coreapi.util.math.Mat4f; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL32; + +public class SSAOShader extends AbstractShaderRenderer +{ + public static SSAOShader INSTANCE = new SSAOShader(); + + + // uniforms + private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms(); + + private static class SsaoShaderUniforms + { + public int gProjUniform; + public int gInvProjUniform; + public int gSampleCountUniform; + public int gRadiusUniform; + public int gStrengthUniform; + public int gMinLightUniform; + public int gBiasUniform; + public int gDepthMapUniform; + } + + + @Override + public void init() + { + super.init(); + + this.shader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag", + "fragColor", new String[]{"vPosition"}); + + // uniform setup + this.ssaoShaderUniforms.gProjUniform = this.shader.getUniformLocation("gProj"); + this.ssaoShaderUniforms.gInvProjUniform = this.shader.getUniformLocation("gInvProj"); + this.ssaoShaderUniforms.gSampleCountUniform = this.shader.getUniformLocation("gSampleCount"); + this.ssaoShaderUniforms.gRadiusUniform = this.shader.getUniformLocation("gRadius"); + this.ssaoShaderUniforms.gStrengthUniform = this.shader.getUniformLocation("gStrength"); + this.ssaoShaderUniforms.gMinLightUniform = this.shader.getUniformLocation("gMinLight"); + this.ssaoShaderUniforms.gBiasUniform = this.shader.getUniformLocation("gBias"); + this.ssaoShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); + } + + void setShaderUniforms(float partialTicks) + { + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); + float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)); + + Mat4f perspective = Mat4f.perspective( + (float) MC_RENDER.getFov(partialTicks), + width / (float) height, + near, far); + + Mat4f invertedPerspective = new Mat4f(perspective); + invertedPerspective.invert(); + + this.shader.setUniform(this.ssaoShaderUniforms.gProjUniform, perspective); + + this.shader.setUniform(this.ssaoShaderUniforms.gInvProjUniform, invertedPerspective); + + this.shader.setUniform(this.ssaoShaderUniforms.gSampleCountUniform, + Config.Client.Advanced.Graphics.Ssao.sampleCount.get()); + + this.shader.setUniform(this.ssaoShaderUniforms.gRadiusUniform, + Config.Client.Advanced.Graphics.Ssao.radius.get().floatValue()); + + this.shader.setUniform(this.ssaoShaderUniforms.gStrengthUniform, + Config.Client.Advanced.Graphics.Ssao.strength.get().floatValue()); + + this.shader.setUniform(this.ssaoShaderUniforms.gMinLightUniform, + Config.Client.Advanced.Graphics.Ssao.minLight.get().floatValue()); + + this.shader.setUniform(this.ssaoShaderUniforms.gBiasUniform, + Config.Client.Advanced.Graphics.Ssao.bias.get().floatValue()); + + GL32.glActiveTexture(GL32.GL_TEXTURE0); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); + + GL32.glUniform1i(this.ssaoShaderUniforms.gDepthMapUniform, 0); + } + + + //========// + // render // + //========// + + public void render(float partialTicks, int ssaoFramebuffer) + { + this.init(); + + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + + this.shader.bind(); + + setShaderUniforms(partialTicks); + + GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, ssaoFramebuffer); + GL32.glViewport(0, 0, width, height); + GL32.glDisable(GL32.GL_SCISSOR_TEST); + GL32.glDisable(GL32.GL_DEPTH_TEST); + GL32.glDisable(GL11.GL_BLEND); + + ScreenQuad.INSTANCE.render(); + + shader.unbind(); + } +} From 22281d477c5804e2f575da283b3aacb6701a23ad Mon Sep 17 00:00:00 2001 From: NULL511 Date: Sun, 10 Sep 2023 01:37:55 -0400 Subject: [PATCH 02/12] fix shader init; remove GL11 --- .../core/render/glObject/GLProxy.java | 44 +++++++++---------- .../shaders/AbstractShaderRenderer.java | 6 +-- .../render/renderer/shaders/DarkShader.java | 1 + .../render/renderer/shaders/FogShader.java | 35 ++++++++++----- .../renderer/shaders/SSAOApplyShader.java | 1 + .../render/renderer/shaders/SSAOShader.java | 4 +- .../vertexFormat/LodVertexFormatElement.java | 16 +++---- .../main/resources/shaders/flat_shaded.frag | 7 +++ 8 files changed, 67 insertions(+), 47 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java index 74f79c21a..da4d5c7fe 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java @@ -19,34 +19,32 @@ package com.seibel.distanthorizons.core.render.glObject; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.seibel.distanthorizons.api.enums.config.EGLErrorHandlingMode; +import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod; +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.enums.EGLProxyContext; +import com.seibel.distanthorizons.core.logging.ConfigBasedLogger; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.util.objects.GLMessage; +import com.seibel.distanthorizons.core.util.objects.GLMessageOutputStream; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.coreapi.ModInfo; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.opengl.GL; +import org.lwjgl.opengl.GL32; +import org.lwjgl.opengl.GLCapabilities; +import org.lwjgl.opengl.GLUtil; + import java.io.PrintStream; import java.lang.invoke.MethodHandles; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import com.seibel.distanthorizons.api.enums.config.EGLErrorHandlingMode; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.ConfigBasedLogger; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.lwjgl.glfw.GLFW; -import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GLCapabilities; -import org.lwjgl.opengl.GLUtil; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.seibel.distanthorizons.coreapi.ModInfo; -import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod; -import com.seibel.distanthorizons.core.enums.EGLProxyContext; -import com.seibel.distanthorizons.core.util.objects.GLMessage; -import com.seibel.distanthorizons.core.util.objects.GLMessageOutputStream; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; - /** * A singleton that holds references to different openGL contexts * and GPU capabilities. @@ -108,7 +106,7 @@ public class GLProxy // this must be created on minecraft's render context to work correctly GL_LOGGER.info("Creating " + GLProxy.class.getSimpleName() + "... If this is the last message you see there must have been an OpenGL error."); - GL_LOGGER.info("Lod Render OpenGL version [" + GL11.glGetString(GL11.GL_VERSION) + "]."); + GL_LOGGER.info("Lod Render OpenGL version [" + GL32.glGetString(GL32.GL_VERSION) + "]."); // getting Minecraft's context has to be done on the render thread, // where the GL context is diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java index 3f9155c1d..7c84e180a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java @@ -30,15 +30,15 @@ public abstract class AbstractShaderRenderer protected ShaderProgram shader; - boolean init = false; + protected boolean init = false; protected AbstractShaderRenderer() {} public void init() { - if (init) return; - init = true; + //if (init) return false; + this.init = true; } public void free() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java index 1028942ea..0c5070317 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java @@ -32,6 +32,7 @@ public class DarkShader extends AbstractShaderRenderer @Override public void init() { + if (this.init) return; super.init(); this.shader = new ShaderProgram( diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 7349271d8..4e1ed2f30 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -44,27 +44,37 @@ public class FogShader extends AbstractShaderRenderer private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class); - public final int gInvertedModelViewProjectionUniform; - public final int gDepthMapUniform; + private final LodFogConfig fogConfig; + public int gInvertedModelViewProjectionUniform; + public int gDepthMapUniform; // Fog Uniforms - public final int fogColorUniform; - public final int fogScaleUniform; - public final int fogVerticalScaleUniform; - public final int nearFogStartUniform; - public final int nearFogLengthUniform; - public final int fullFogModeUniform; + public int fogColorUniform; + public int fogScaleUniform; + public int fogVerticalScaleUniform; + public int nearFogStartUniform; + public int nearFogLengthUniform; + public int fullFogModeUniform; public FogShader(LodFogConfig fogConfig) { + this.fogConfig = fogConfig; + } + + @Override + public void init() + { + if (this.init) return; + super.init(); + this.shader = new ShaderProgram( // TODO rename normal.vert to something like "postProcess.vert" () -> Shader.loadFile("shaders/normal.vert", false, new StringBuilder()).toString(), - () -> fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(), + () -> this.fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(), "fragColor", new String[]{"vPosition"} ); - + // all uniforms should be tryGet... // because disabling fog can cause the GLSL to optimize out most (if not all) uniforms @@ -131,6 +141,8 @@ public class FogShader extends AbstractShaderRenderer public void setModelViewProjectionMatrix(Mat4f combinedModelViewProjectionMatrix) { + this.init(); + this.shader.bind(); Mat4f inverseMvmProjMatrix = new Mat4f(combinedModelViewProjectionMatrix); @@ -167,4 +179,5 @@ public class FogShader extends AbstractShaderRenderer ScreenQuad.INSTANCE.render(); state.restore(); - }} + } +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index fb85a4bb5..288e8414c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -48,6 +48,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer @Override public void init() { + if (this.init) return; super.init(); this.shader = new ShaderProgram( diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index 9fe7e2fbe..27a49f268 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -25,7 +25,6 @@ import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.coreapi.util.math.Mat4f; -import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL32; public class SSAOShader extends AbstractShaderRenderer @@ -52,6 +51,7 @@ public class SSAOShader extends AbstractShaderRenderer @Override public void init() { + if (this.init) return; super.init(); this.shader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag", @@ -128,7 +128,7 @@ public class SSAOShader extends AbstractShaderRenderer GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glDisable(GL32.GL_DEPTH_TEST); - GL32.glDisable(GL11.GL_BLEND); + GL32.glDisable(GL32.GL_BLEND); ScreenQuad.INSTANCE.render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java b/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java index 6d506cef7..f4f08eccd 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java @@ -19,7 +19,7 @@ package com.seibel.distanthorizons.core.render.vertexFormat; -import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL32; /** * This object is used to build LodVertexFormats. @@ -80,13 +80,13 @@ public class LodVertexFormatElement public enum DataType { - FLOAT(4, "Float", GL11.GL_FLOAT), - UBYTE(1, "Unsigned Byte", GL11.GL_UNSIGNED_BYTE), - BYTE(1, "Byte", GL11.GL_BYTE), - USHORT(2, "Unsigned Short", GL11.GL_UNSIGNED_SHORT), - SHORT(2, "Short", GL11.GL_SHORT), - UINT(4, "Unsigned Int", GL11.GL_UNSIGNED_INT), - INT(4, "Int", GL11.GL_INT); + FLOAT(4, "Float", GL32.GL_FLOAT), + UBYTE(1, "Unsigned Byte", GL32.GL_UNSIGNED_BYTE), + BYTE(1, "Byte", GL32.GL_BYTE), + USHORT(2, "Unsigned Short", GL32.GL_UNSIGNED_SHORT), + SHORT(2, "Short", GL32.GL_SHORT), + UINT(4, "Unsigned Int", GL32.GL_UNSIGNED_INT), + INT(4, "Int", GL32.GL_INT); private final int size; private final String name; diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index edcddbcca..574192f19 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -28,6 +28,10 @@ vec3 quantize(vec3 val, int stepSize) { return floor(val * stepSize) / stepSize; } +vec3 RgbToLinear(const in vec3 color) { + return pow(color, vec3(2.2)); +} + /** * Fragment Shader @@ -40,6 +44,9 @@ void main() { fragColor = vertexColor; + // WARN: DEBUG TEST! + //fragColor.rgb = RgbToLinear(fragColor.rgb) * 3.0; + // TODO: Move into its own function instead of in an if statement if (noiseEnabled) { vec3 vertexNormal = normalize(cross(dFdy(vPos.xyz), dFdx(vPos.xyz))); From a37b0abd18580bf943e38cfa53887b07879cadae Mon Sep 17 00:00:00 2001 From: NULL511 Date: Sun, 10 Sep 2023 03:14:03 -0400 Subject: [PATCH 03/12] use init render events --- .../core/render/renderer/SSAORenderer.java | 8 +++---- .../core/render/renderer/ScreenQuad.java | 7 ++---- .../shaders/AbstractShaderRenderer.java | 23 +++++++++++++++++- .../render/renderer/shaders/DarkShader.java | 21 +++++----------- .../render/renderer/shaders/FogShader.java | 24 ++++++------------- .../renderer/shaders/SSAOApplyShader.java | 21 +++++++--------- .../render/renderer/shaders/SSAOShader.java | 24 +++++++------------ .../main/resources/shaders/flat_shaded.frag | 7 ------ 8 files changed, 57 insertions(+), 78 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java index a3e9f2c09..0cbb038d1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java @@ -106,13 +106,13 @@ public class SSAORenderer this.createFramebuffer(width, height); } - ScreenQuad.INSTANCE.bind(); - - SSAOShader.INSTANCE.render(partialTicks, ssaoFramebuffer); + SSAOShader.INSTANCE.ssaoFramebuffer = this.ssaoFramebuffer; + SSAOShader.INSTANCE.render(partialTicks); primaryState.RestoreFrameBuffer(); - SSAOApplyShader.INSTANCE.render(partialTicks, ssaoTexture); + SSAOApplyShader.INSTANCE.ssaoTexture = this.ssaoTexture; + SSAOApplyShader.INSTANCE.render(partialTicks); state.restore(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java index 774a3a289..aa3014b1b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java @@ -67,16 +67,13 @@ public class ScreenQuad this.createBuffer(); } - public void bind() + public void render() { this.init(); this.va.bind(); this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId()); - } - - public void render() - { + GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java index 7c84e180a..c707b7092 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java @@ -37,12 +37,33 @@ public abstract class AbstractShaderRenderer public void init() { - //if (init) return false; + if (this.init) return; this.init = true; + + this.onInit(); + } + + public void render(float partialTicks) + { + this.init(); + + this.shader.bind(); + + this.onApplyUniforms(partialTicks); + + this.onRender(); + + this.shader.unbind(); } public void free() { this.shader.free(); } + + protected void onInit() {} + + protected void onApplyUniforms(float partialTicks) {} + + protected void onRender() {} } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java index 0c5070317..d13a023d1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java @@ -30,11 +30,8 @@ public class DarkShader extends AbstractShaderRenderer @Override - public void init() + public void onInit() { - if (this.init) return; - super.init(); - this.shader = new ShaderProgram( "shaders/normal.vert", "shaders/test/dark.frag", @@ -42,17 +39,17 @@ public class DarkShader extends AbstractShaderRenderer new String[]{"vPosition", "color"}); } - void setShaderUniforms() + @Override + protected void onApplyUniforms(float partialTicks) { GL32.glActiveTexture(GL32.GL_TEXTURE0); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); } - public void render() + @Override + protected void onRender() { GLState state = new GLState(); - - this.init(); int width = MC_RENDER.getTargetFrameBufferViewportWidth(); int height = MC_RENDER.getTargetFrameBufferViewportHeight(); @@ -60,15 +57,9 @@ public class DarkShader extends AbstractShaderRenderer GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_SCISSOR_TEST); - - shader.bind(); - - this.setShaderUniforms(); - - ScreenQuad.INSTANCE.bind(); - GL32.glEnable(GL32.GL_BLEND); GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); + ScreenQuad.INSTANCE.render(); state.restore(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 4e1ed2f30..183bbbe74 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -63,11 +63,8 @@ public class FogShader extends AbstractShaderRenderer } @Override - public void init() + public void onInit() { - if (this.init) return; - super.init(); - this.shader = new ShaderProgram( // TODO rename normal.vert to something like "postProcess.vert" () -> Shader.loadFile("shaders/normal.vert", false, new StringBuilder()).toString(), @@ -92,8 +89,8 @@ public class FogShader extends AbstractShaderRenderer this.nearFogLengthUniform = this.shader.tryGetUniformLocation("nearFogLength"); } - //@Override - void setShaderUniforms(float partialTicks) + @Override + protected void onApplyUniforms(float partialTicks) { this.shader.bind(); @@ -152,30 +149,23 @@ public class FogShader extends AbstractShaderRenderer this.shader.unbind(); } - public void render(float partialTicks) + @Override + protected void onRender() { GLState state = new GLState(); - this.init(); - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); int height = MC_RENDER.getTargetFrameBufferViewportHeight(); GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_SCISSOR_TEST); - - shader.bind(); - - this.setShaderUniforms(partialTicks); - - ScreenQuad.INSTANCE.bind(); + GL32.glEnable(GL32.GL_BLEND); + GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); GL32.glActiveTexture(GL32.GL_TEXTURE0); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - GL32.glEnable(GL32.GL_BLEND); - GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); ScreenQuad.INSTANCE.render(); state.restore(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index 288e8414c..44140cb56 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -30,6 +30,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer { public static SSAOApplyShader INSTANCE = new SSAOApplyShader(); + public int ssaoTexture; // apply uniforms private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms(); @@ -46,11 +47,8 @@ public class SSAOApplyShader extends AbstractShaderRenderer @Override - public void init() + public void onInit() { - if (this.init) return; - super.init(); - this.shader = new ShaderProgram( "shaders/normal.vert", "shaders/ssao/apply.frag", @@ -66,14 +64,15 @@ public class SSAOApplyShader extends AbstractShaderRenderer this.applyShaderUniforms.gFarUniform = this.shader.tryGetUniformLocation("gFar"); } - private void setShaderUniforms(float partialTicks, int ssaoTexture) + @Override + protected void onApplyUniforms(float partialTicks) { GL32.glActiveTexture(GL32.GL_TEXTURE0); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0); GL32.glActiveTexture(GL32.GL_TEXTURE1); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, ssaoTexture); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1); int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get(); @@ -99,18 +98,14 @@ public class SSAOApplyShader extends AbstractShaderRenderer } } + //========// // render // //========// - public void render(float partialTicks, int ssaoTexture) + @Override + protected void onRender() { - this.init(); - - this.shader.bind(); - - setShaderUniforms(partialTicks, ssaoTexture); - GL32.glEnable(GL32.GL_BLEND); GL32.glBlendEquation(GL32.GL_FUNC_ADD); GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index 27a49f268..d79ecc446 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -31,6 +31,7 @@ public class SSAOShader extends AbstractShaderRenderer { public static SSAOShader INSTANCE = new SSAOShader(); + public int ssaoFramebuffer; // uniforms private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms(); @@ -46,14 +47,11 @@ public class SSAOShader extends AbstractShaderRenderer public int gBiasUniform; public int gDepthMapUniform; } - + @Override - public void init() + public void onInit() { - if (this.init) return; - super.init(); - this.shader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag", "fragColor", new String[]{"vPosition"}); @@ -68,7 +66,8 @@ public class SSAOShader extends AbstractShaderRenderer this.ssaoShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); } - void setShaderUniforms(float partialTicks) + @Override + protected void onApplyUniforms(float partialTicks) { int width = MC_RENDER.getTargetFrameBufferViewportWidth(); int height = MC_RENDER.getTargetFrameBufferViewportHeight(); @@ -113,25 +112,18 @@ public class SSAOShader extends AbstractShaderRenderer // render // //========// - public void render(float partialTicks, int ssaoFramebuffer) + @Override + protected void onRender() { - this.init(); - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - this.shader.bind(); - - setShaderUniforms(partialTicks); - - GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, ssaoFramebuffer); + GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_BLEND); ScreenQuad.INSTANCE.render(); - - shader.unbind(); } } diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index 574192f19..edcddbcca 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -28,10 +28,6 @@ vec3 quantize(vec3 val, int stepSize) { return floor(val * stepSize) / stepSize; } -vec3 RgbToLinear(const in vec3 color) { - return pow(color, vec3(2.2)); -} - /** * Fragment Shader @@ -44,9 +40,6 @@ void main() { fragColor = vertexColor; - // WARN: DEBUG TEST! - //fragColor.rgb = RgbToLinear(fragColor.rgb) * 3.0; - // TODO: Move into its own function instead of in an if statement if (noiseEnabled) { vec3 vertexNormal = normalize(cross(dFdy(vPos.xyz), dFdx(vPos.xyz))); From 25f4ef322423364248c0033ca0fc2bda4872348d Mon Sep 17 00:00:00 2001 From: NULL511 Date: Sun, 10 Sep 2023 03:38:47 -0400 Subject: [PATCH 04/12] default viewport --- .../renderer/shaders/AbstractShaderRenderer.java | 5 +++++ .../core/render/renderer/shaders/DarkShader.java | 6 +----- .../core/render/renderer/shaders/FogShader.java | 4 ---- .../render/renderer/shaders/SSAOApplyShader.java | 14 +++++++------- .../core/render/renderer/shaders/SSAOShader.java | 4 ---- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java index c707b7092..c098da287 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import org.lwjgl.opengl.GL32; public abstract class AbstractShaderRenderer { @@ -51,6 +52,10 @@ public abstract class AbstractShaderRenderer this.onApplyUniforms(partialTicks); + int width = MC_RENDER.getTargetFrameBufferViewportWidth(); + int height = MC_RENDER.getTargetFrameBufferViewportHeight(); + GL32.glViewport(0, 0, width, height); + this.onRender(); this.shader.unbind(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java index d13a023d1..0e9341faa 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DarkShader.java @@ -50,11 +50,7 @@ public class DarkShader extends AbstractShaderRenderer protected void onRender() { GLState state = new GLState(); - - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - - GL32.glViewport(0, 0, width, height); + GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glEnable(GL32.GL_BLEND); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 183bbbe74..22b762b4f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -154,10 +154,6 @@ public class FogShader extends AbstractShaderRenderer { GLState state = new GLState(); - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - - GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glEnable(GL32.GL_BLEND); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index 44140cb56..44776d154 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -75,20 +75,20 @@ public class SSAOApplyShader extends AbstractShaderRenderer GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1); - int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get(); - GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius); + GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, + Config.Client.Advanced.Graphics.Ssao.blurRadius.get()); if (this.applyShaderUniforms.gViewSizeUniform >= 0) { - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height); + GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, + MC_RENDER.getTargetFrameBufferViewportWidth(), + MC_RENDER.getTargetFrameBufferViewportHeight()); } if (this.applyShaderUniforms.gNearUniform >= 0) { - float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); - GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, near); + GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, + RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks)); } if (this.applyShaderUniforms.gFarUniform >= 0) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index d79ecc446..88e02a7cb 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -115,11 +115,7 @@ public class SSAOShader extends AbstractShaderRenderer @Override protected void onRender() { - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); - GL32.glViewport(0, 0, width, height); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_BLEND); From 8f42acbd65cec9ab856af9643a1bc91dd1734bc8 Mon Sep 17 00:00:00 2001 From: NULL511 Date: Sun, 10 Sep 2023 04:15:35 -0400 Subject: [PATCH 05/12] simplify matrix usage; uniform cleanup --- .../core/render/renderer/LodRenderer.java | 11 ++- .../core/render/renderer/SSAORenderer.java | 4 +- .../render/renderer/shaders/FogShader.java | 14 +--- .../renderer/shaders/SSAOApplyShader.java | 53 ++++++------ .../render/renderer/shaders/SSAOShader.java | 83 +++++++++---------- 5 files changed, 76 insertions(+), 89 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index dee4ede60..2d9609681 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -243,16 +243,23 @@ public class LodRenderer { this.shaderProgram.free(); this.shaderProgram = new LodRenderProgram(newFogConfig); + FogShader.INSTANCE.free(); FogShader.INSTANCE = new FogShader(newFogConfig); } this.shaderProgram.bind(); } + GL32.glActiveTexture(GL32.GL_TEXTURE0); /*---------Get required data--------*/ int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; - Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks); + //Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks); + + Mat4f projectionMatrix = RenderUtil.createLodProjectionMatrix(baseProjectionMatrix, partialTicks); + + Mat4f modelViewProjectionMatrix = new Mat4f(projectionMatrix); + modelViewProjectionMatrix.multiply(RenderUtil.createLodModelViewMatrix(baseModelViewMatrix)); /*---------Fill uniform data--------*/ this.shaderProgram.fillUniformData(modelViewProjectionMatrix, /*Light map = GL_TEXTURE0*/ 0, @@ -283,12 +290,12 @@ public class LodRenderer if (Config.Client.Advanced.Graphics.Ssao.enabled.get()) { profiler.popPush("LOD SSAO"); + SSAOShader.INSTANCE.setProjectionMatrix(projectionMatrix); SSAORenderer.INSTANCE.render(minecraftGlState, partialTicks); } profiler.popPush("LOD Fog"); - // TODO add the model view/projection matrices to the render() function FogShader.INSTANCE.setModelViewProjectionMatrix(modelViewProjectionMatrix); FogShader.INSTANCE.render(partialTicks); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java index 0cbb038d1..9a52a753a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java @@ -106,12 +106,12 @@ public class SSAORenderer this.createFramebuffer(width, height); } - SSAOShader.INSTANCE.ssaoFramebuffer = this.ssaoFramebuffer; + SSAOShader.INSTANCE.FrameBuffer = this.ssaoFramebuffer; SSAOShader.INSTANCE.render(partialTicks); primaryState.RestoreFrameBuffer(); - SSAOApplyShader.INSTANCE.ssaoTexture = this.ssaoTexture; + SSAOApplyShader.INSTANCE.BufferTexture = this.ssaoTexture; SSAOApplyShader.INSTANCE.render(partialTicks); state.restore(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 22b762b4f..d66b06eb8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -45,6 +45,7 @@ public class FogShader extends AbstractShaderRenderer private final LodFogConfig fogConfig; + private Mat4f inverseMvmProjMatrix; public int gInvertedModelViewProjectionUniform; public int gDepthMapUniform; @@ -92,7 +93,7 @@ public class FogShader extends AbstractShaderRenderer @Override protected void onApplyUniforms(float partialTicks) { - this.shader.bind(); + this.shader.setUniform(this.gInvertedModelViewProjectionUniform, this.inverseMvmProjMatrix); int lodDrawDistance = RenderUtil.getFarClipPlaneDistanceInBlocks(); int vanillaDrawDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; @@ -138,15 +139,8 @@ public class FogShader extends AbstractShaderRenderer public void setModelViewProjectionMatrix(Mat4f combinedModelViewProjectionMatrix) { - this.init(); - - this.shader.bind(); - - Mat4f inverseMvmProjMatrix = new Mat4f(combinedModelViewProjectionMatrix); - inverseMvmProjMatrix.invert(); - this.shader.setUniform(this.gInvertedModelViewProjectionUniform, inverseMvmProjMatrix); - - this.shader.unbind(); + this.inverseMvmProjMatrix = new Mat4f(combinedModelViewProjectionMatrix); + this.inverseMvmProjMatrix.invert(); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index 44776d154..66d1dbfbe 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -30,20 +30,15 @@ public class SSAOApplyShader extends AbstractShaderRenderer { public static SSAOApplyShader INSTANCE = new SSAOApplyShader(); - public int ssaoTexture; + public int BufferTexture; - // apply uniforms - private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms(); - - private static class ApplyShaderUniforms - { - public int gSSAOMapUniform; - public int gDepthMapUniform; - public int gViewSizeUniform; - public int gBlurRadiusUniform; - public int gNearUniform; - public int gFarUniform; - } + // uniforms + public int gSSAOMapUniform; + public int gDepthMapUniform; + public int gViewSizeUniform; + public int gBlurRadiusUniform; + public int gNearUniform; + public int gFarUniform; @Override @@ -56,12 +51,12 @@ public class SSAOApplyShader extends AbstractShaderRenderer new String[]{"vPosition"}); // uniform setup - this.applyShaderUniforms.gSSAOMapUniform = this.shader.getUniformLocation("gSSAOMap"); - this.applyShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); - this.applyShaderUniforms.gViewSizeUniform = this.shader.tryGetUniformLocation("gViewSize"); - this.applyShaderUniforms.gBlurRadiusUniform = this.shader.tryGetUniformLocation("gBlurRadius"); - this.applyShaderUniforms.gNearUniform = this.shader.tryGetUniformLocation("gNear"); - this.applyShaderUniforms.gFarUniform = this.shader.tryGetUniformLocation("gFar"); + this.gSSAOMapUniform = this.shader.getUniformLocation("gSSAOMap"); + this.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); + this.gViewSizeUniform = this.shader.tryGetUniformLocation("gViewSize"); + this.gBlurRadiusUniform = this.shader.tryGetUniformLocation("gBlurRadius"); + this.gNearUniform = this.shader.tryGetUniformLocation("gNear"); + this.gFarUniform = this.shader.tryGetUniformLocation("gFar"); } @Override @@ -69,32 +64,32 @@ public class SSAOApplyShader extends AbstractShaderRenderer { GL32.glActiveTexture(GL32.GL_TEXTURE0); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0); + GL32.glUniform1i(this.gDepthMapUniform, 0); GL32.glActiveTexture(GL32.GL_TEXTURE1); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture); - GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.BufferTexture); + GL32.glUniform1i(this.gSSAOMapUniform, 1); - GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, + GL32.glUniform1i(this.gBlurRadiusUniform, Config.Client.Advanced.Graphics.Ssao.blurRadius.get()); - if (this.applyShaderUniforms.gViewSizeUniform >= 0) + if (this.gViewSizeUniform >= 0) { - GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, + GL32.glUniform2f(this.gViewSizeUniform, MC_RENDER.getTargetFrameBufferViewportWidth(), MC_RENDER.getTargetFrameBufferViewportHeight()); } - if (this.applyShaderUniforms.gNearUniform >= 0) + if (this.gNearUniform >= 0) { - GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, + GL32.glUniform1f(this.gNearUniform, RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks)); } - if (this.applyShaderUniforms.gFarUniform >= 0) + if (this.gFarUniform >= 0) { float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)); - GL32.glUniform1f(this.applyShaderUniforms.gFarUniform, far); + GL32.glUniform1f(this.gFarUniform, far); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index 88e02a7cb..34eee4b96 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -22,8 +22,6 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.coreapi.util.math.Mat4f; import org.lwjgl.opengl.GL32; @@ -31,22 +29,20 @@ public class SSAOShader extends AbstractShaderRenderer { public static SSAOShader INSTANCE = new SSAOShader(); - public int ssaoFramebuffer; + public int FrameBuffer; + + private Mat4f perspective; + private Mat4f invertedPerspective; // uniforms - private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms(); - - private static class SsaoShaderUniforms - { - public int gProjUniform; - public int gInvProjUniform; - public int gSampleCountUniform; - public int gRadiusUniform; - public int gStrengthUniform; - public int gMinLightUniform; - public int gBiasUniform; - public int gDepthMapUniform; - } + public int gProjUniform; + public int gInvProjUniform; + public int gSampleCountUniform; + public int gRadiusUniform; + public int gStrengthUniform; + public int gMinLightUniform; + public int gBiasUniform; + public int gDepthMapUniform; @Override @@ -56,55 +52,50 @@ public class SSAOShader extends AbstractShaderRenderer "fragColor", new String[]{"vPosition"}); // uniform setup - this.ssaoShaderUniforms.gProjUniform = this.shader.getUniformLocation("gProj"); - this.ssaoShaderUniforms.gInvProjUniform = this.shader.getUniformLocation("gInvProj"); - this.ssaoShaderUniforms.gSampleCountUniform = this.shader.getUniformLocation("gSampleCount"); - this.ssaoShaderUniforms.gRadiusUniform = this.shader.getUniformLocation("gRadius"); - this.ssaoShaderUniforms.gStrengthUniform = this.shader.getUniformLocation("gStrength"); - this.ssaoShaderUniforms.gMinLightUniform = this.shader.getUniformLocation("gMinLight"); - this.ssaoShaderUniforms.gBiasUniform = this.shader.getUniformLocation("gBias"); - this.ssaoShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); + this.gProjUniform = this.shader.getUniformLocation("gProj"); + this.gInvProjUniform = this.shader.getUniformLocation("gInvProj"); + this.gSampleCountUniform = this.shader.getUniformLocation("gSampleCount"); + this.gRadiusUniform = this.shader.getUniformLocation("gRadius"); + this.gStrengthUniform = this.shader.getUniformLocation("gStrength"); + this.gMinLightUniform = this.shader.getUniformLocation("gMinLight"); + this.gBiasUniform = this.shader.getUniformLocation("gBias"); + this.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); + } + + public void setProjectionMatrix(Mat4f perspective) + { + this.perspective = perspective; + + this.invertedPerspective = new Mat4f(perspective); + this.invertedPerspective.invert(); } @Override protected void onApplyUniforms(float partialTicks) { - int width = MC_RENDER.getTargetFrameBufferViewportWidth(); - int height = MC_RENDER.getTargetFrameBufferViewportHeight(); - float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); - float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)); + this.shader.setUniform(this.gProjUniform, this.perspective); - Mat4f perspective = Mat4f.perspective( - (float) MC_RENDER.getFov(partialTicks), - width / (float) height, - near, far); + this.shader.setUniform(this.gInvProjUniform, this.invertedPerspective); - Mat4f invertedPerspective = new Mat4f(perspective); - invertedPerspective.invert(); - - this.shader.setUniform(this.ssaoShaderUniforms.gProjUniform, perspective); - - this.shader.setUniform(this.ssaoShaderUniforms.gInvProjUniform, invertedPerspective); - - this.shader.setUniform(this.ssaoShaderUniforms.gSampleCountUniform, + this.shader.setUniform(this.gSampleCountUniform, Config.Client.Advanced.Graphics.Ssao.sampleCount.get()); - this.shader.setUniform(this.ssaoShaderUniforms.gRadiusUniform, + this.shader.setUniform(this.gRadiusUniform, Config.Client.Advanced.Graphics.Ssao.radius.get().floatValue()); - this.shader.setUniform(this.ssaoShaderUniforms.gStrengthUniform, + this.shader.setUniform(this.gStrengthUniform, Config.Client.Advanced.Graphics.Ssao.strength.get().floatValue()); - this.shader.setUniform(this.ssaoShaderUniforms.gMinLightUniform, + this.shader.setUniform(this.gMinLightUniform, Config.Client.Advanced.Graphics.Ssao.minLight.get().floatValue()); - this.shader.setUniform(this.ssaoShaderUniforms.gBiasUniform, + this.shader.setUniform(this.gBiasUniform, Config.Client.Advanced.Graphics.Ssao.bias.get().floatValue()); GL32.glActiveTexture(GL32.GL_TEXTURE0); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); - GL32.glUniform1i(this.ssaoShaderUniforms.gDepthMapUniform, 0); + GL32.glUniform1i(this.gDepthMapUniform, 0); } @@ -115,7 +106,7 @@ public class SSAOShader extends AbstractShaderRenderer @Override protected void onRender() { - GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); + GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.FrameBuffer); GL32.glDisable(GL32.GL_SCISSOR_TEST); GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDisable(GL32.GL_BLEND); From d3865551a56b94b7fde500d09c1a181fafe1a827 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 10 Sep 2023 17:09:33 -0500 Subject: [PATCH 06/12] Minor Lighting Engine GC optimizations --- .../core/api/internal/ServerApi.java | 3 +- .../core/generation/DhLightingEngine.java | 48 ++++++++++++------- .../distanthorizons/core/pos/DhBlockPos.java | 12 ++--- .../chunk/IChunkWrapper.java | 3 +- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java index d18ff93c3..241fb7ae9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java @@ -37,6 +37,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.apache.logging.log4j.Logger; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ThreadPoolExecutor; @@ -204,7 +205,7 @@ public class ServerApi { // generate the chunk's lighting, ignoring neighbors. // not a perfect solution, but should prevent chunks from having completely broken lighting - List nearbyChunkList = new LinkedList<>(); + ArrayList nearbyChunkList = new ArrayList<>(1); nearbyChunkList.add(chunkWrapper); DhLightingEngine.INSTANCE.lightChunk(chunkWrapper, nearbyChunkList, level.hasSkyLight() ? 15 : 0); chunkWrapper.setUseDhLighting(true); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index ece655536..47d3066e4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -19,7 +19,6 @@ package com.seibel.distanthorizons.core.generation; -import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhBlockPos; @@ -42,6 +41,15 @@ public class DhLightingEngine private static final Logger LOGGER = DhLoggerBuilder.getLogger(); public static final DhLightingEngine INSTANCE = new DhLightingEngine(); + /** + * Minor garbage collection optimization.
+ * Since these objects are always mutated anyway, using a {@link ThreadLocal} will allow us to + * only create as many of these {@link DhBlockPos} as necessary. + */ + private static final ThreadLocal PRIMARY_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new DhBlockPos()); + private static final ThreadLocal SECONDARY_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new DhBlockPos()); + + private DhLightingEngine() { } @@ -56,7 +64,7 @@ public class DhLightingEngine * @param nearbyChunkList should also contain centerChunk * @param maxSkyLight should be a value between 0 and 15 */ - public void lightChunk(IChunkWrapper centerChunk, List nearbyChunkList, int maxSkyLight) + public void lightChunk(IChunkWrapper centerChunk, ArrayList nearbyChunkList, int maxSkyLight) { DhChunkPos centerChunkPos = centerChunk.getChunkPos(); AdjacentChunkHolder adjacentChunkHolder = new AdjacentChunkHolder(centerChunk); @@ -88,8 +96,10 @@ public class DhLightingEngine // find all adjacent chunks // and get any necessary info from them boolean warningLogged = false; - for (IChunkWrapper chunk : nearbyChunkList) + for (int chunkIndex = 0; chunkIndex < nearbyChunkList.size(); chunkIndex++) // using iterators in high traffic areas can cause GC issues due to allocating a bunch of iterators, use an indexed for-loop instead { + IChunkWrapper chunk = nearbyChunkList.get(chunkIndex); + if (chunk != null && requestedAdjacentPositions.contains(chunk.getChunkPos())) { // remove the newly found position @@ -101,17 +111,22 @@ public class DhLightingEngine // get and set the adjacent chunk's initial block lights - List blockLightPosList = chunk.getBlockLightPosList(); - for (DhBlockPos blockLightPos : blockLightPosList) + final DhBlockPos relLightBlockPos = PRIMARY_BLOCK_POS_REF.get(); + final DhBlockPos relBlockPos = SECONDARY_BLOCK_POS_REF.get(); + + ArrayList blockLightPosList = chunk.getBlockLightPosList(); + for (int blockLightIndex = 0; blockLightIndex < blockLightPosList.size(); blockLightIndex++) // using iterators in high traffic areas can cause GC issues due to allocating a bunch of iterators, use an indexed for-loop instead { + DhBlockPos blockLightPos = blockLightPosList.get(blockLightIndex); + blockLightPos.mutateToChunkRelativePos(relLightBlockPos); + // get the light - DhBlockPos relLightBlockPos = blockLightPos.convertToChunkRelativePos(); IBlockStateWrapper blockState = chunk.getBlockState(relLightBlockPos); int lightValue = blockState.getLightEmission(); blockLightPosQueue.push(blockLightPos.x, blockLightPos.y, blockLightPos.z, lightValue); // set the light - DhBlockPos relBlockPos = blockLightPos.convertToChunkRelativePos(); + blockLightPos.mutateToChunkRelativePos(relBlockPos); chunk.setDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, lightValue); } @@ -142,7 +157,7 @@ public class DhLightingEngine // set the light - DhBlockPos relBlockPos = skyLightPos.convertToChunkRelativePos(); + skyLightPos.mutateToChunkRelativePos(relBlockPos); chunk.setDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, maxSkyLight); } } @@ -199,8 +214,8 @@ public class DhLightingEngine { // these objects are saved so they can be mutated throughout the method, // this reduces the number of allocations necessary, reducing GC pressure - final DhBlockPos neighbourBlockPos = new DhBlockPos(); - final DhBlockPos relNeighbourBlockPos = new DhBlockPos(); + final DhBlockPos neighbourBlockPos = PRIMARY_BLOCK_POS_REF.get(); + final DhBlockPos relNeighbourBlockPos = SECONDARY_BLOCK_POS_REF.get(); // update each light position @@ -215,11 +230,10 @@ public class DhLightingEngine // propagate the lighting in each cardinal direction, IE: -x, +x, -y, +y, -z, +z - for (EDhDirection direction : EDhDirection.CARDINAL_DIRECTIONS) + for (EDhDirection direction : EDhDirection.CARDINAL_DIRECTIONS) // since this is an array instead of an ArrayList this advanced for-loop shouldn't cause any GC issues { - pos.offset(direction, neighbourBlockPos); // mutates neighbourBlockPos - // converting the block pos into a relative position is necessary for accessing the light values in the chunk - neighbourBlockPos.convertToChunkRelativePos(relNeighbourBlockPos); // mutates relNeighbourBlockPos + pos.mutateOffset(direction, neighbourBlockPos); + neighbourBlockPos.mutateToChunkRelativePos(relNeighbourBlockPos); // only continue if the light position is inside one of our chunks @@ -313,9 +327,11 @@ public class DhLightingEngine int chunkZ = blockZ >> 4; // since there will only ever be 9 items in the array, this sequential search should be fast enough - for (IChunkWrapper chunk : this.chunkArray) + for (int i = 0; i < this.chunkArray.size(); i++) // using iterators in high traffic areas can cause GC issues due to allocating a bunch of iterators, use an indexed for-loop instead { - if (chunk != null + IChunkWrapper chunk = this.chunkArray.get(i); + + if (chunk != null && chunk.getChunkPos().x == chunkX && chunk.getChunkPos().z == chunkZ) { return chunk; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java index 1e915d335..d07a5da8c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java @@ -130,12 +130,12 @@ public class DhBlockPos } /** creates a new {@link DhBlockPos} with the given offset from the current pos. */ - public DhBlockPos offset(EDhDirection direction) { return this.offset(direction, null); } + public DhBlockPos offset(EDhDirection direction) { return this.mutateOffset(direction, null); } /** if not null, mutates "mutablePos" so it matches the current pos after being offset. Otherwise creates a new {@link DhBlockPos}. */ - public DhBlockPos offset(EDhDirection direction, @Nullable DhBlockPos mutablePos) { return this.offset(direction.getNormal().x, direction.getNormal().y, direction.getNormal().z, mutablePos); } + public DhBlockPos mutateOffset(EDhDirection direction, @Nullable DhBlockPos mutablePos) { return this.mutateOffset(direction.getNormal().x, direction.getNormal().y, direction.getNormal().z, mutablePos); } - public DhBlockPos offset(int x, int y, int z) { return this.offset(x,y,z, null); } - public DhBlockPos offset(int x, int y, int z, @Nullable DhBlockPos mutablePos) + public DhBlockPos offset(int x, int y, int z) { return this.mutateOffset(x,y,z, null); } + public DhBlockPos mutateOffset(int x, int y, int z, @Nullable DhBlockPos mutablePos) { int newX = this.x + x; int newY = this.y + y; @@ -156,12 +156,12 @@ public class DhBlockPos } /** Returns a new {@link DhBlockPos} limits to a value between 0 and 15 (inclusive) */ - public DhBlockPos convertToChunkRelativePos() { return this.convertToChunkRelativePos(null); } + public DhBlockPos convertToChunkRelativePos() { return this.mutateToChunkRelativePos(null); } /** * Limits the block position to a value between 0 and 15 (inclusive) * If not null, mutates "mutableBlockPos" */ - public DhBlockPos convertToChunkRelativePos(@Nullable DhBlockPos mutableBlockPos) + public DhBlockPos mutateToChunkRelativePos(@Nullable DhBlockPos mutableBlockPos) { // move the position into the range -15 and +15 int relX = (this.x % LodUtil.CHUNK_WIDTH); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java index da6b8421e..e8f7a56d9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -28,6 +28,7 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; +import java.util.ArrayList; import java.util.List; public interface IChunkWrapper extends IBindable @@ -98,7 +99,7 @@ public interface IChunkWrapper extends IBindable - List getBlockLightPosList(); + ArrayList getBlockLightPosList(); default boolean blockPosInsideChunk(DhBlockPos blockPos) { return this.blockPosInsideChunk(blockPos.x, blockPos.y, blockPos.z); } From 5ec874d4a0df3e81767c210e62feac41334503af Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 11 Sep 2023 07:25:58 -0500 Subject: [PATCH 07/12] Improve LOD Building and Lighting speed for BigGlobe worlds Thanks Builderb0y! --- .../core/dataObjects/transformers/LodDataBuilder.java | 5 +++-- .../distanthorizons/core/generation/DhLightingEngine.java | 2 +- .../core/wrapperInterfaces/chunk/IChunkWrapper.java | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java index 361d1d1fc..b6513df41 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java @@ -44,6 +44,7 @@ public class LodDataBuilder ChunkSizedFullDataAccessor chunkData = new ChunkSizedFullDataAccessor(chunkWrapper.getChunkPos()); + int minBuildHeight = chunkWrapper.getMinFilledHeight(); for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++) { @@ -71,7 +72,7 @@ public class LodDataBuilder } - for (; y >= chunkWrapper.getMinBuildHeight(); y--) + for (; y >= minBuildHeight; y--) { IBiomeWrapper newBiome = chunkWrapper.getBiome(x, y, z); IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(x, y, z); @@ -94,7 +95,7 @@ public class LodDataBuilder } longs.add(FullDataPointUtil.encode(mappedId, lastY - y, y + 1 - chunkWrapper.getMinBuildHeight(), light)); - chunkData.setSingleColumn(longs.toArray(new long[0]), x, z); + chunkData.setSingleColumn(longs.toLongArray(), x, z); } } if (!canGenerateLodFromChunk(chunkWrapper)) return null; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 47d3066e4..09329c779 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -244,7 +244,7 @@ public class DhLightingEngine continue; } - if (relNeighbourBlockPos.y < neighbourChunk.getMinBuildHeight() || relNeighbourBlockPos.y > neighbourChunk.getMaxBuildHeight()) + if (relNeighbourBlockPos.y < neighbourChunk.getMinFilledHeight() || relNeighbourBlockPos.y > neighbourChunk.getMaxBuildHeight()) { // the light pos is outside the chunk's min/max height, // this can happen if given a chunk that hasn't finished generating diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java index e8f7a56d9..f5a45a22e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -39,6 +39,12 @@ public interface IChunkWrapper extends IBindable int getMinBuildHeight(); int getMaxBuildHeight(); + /** + * returns the Y level for the first non-empty section in this chunk, + * or {@link Integer#MAX_VALUE} if this chunk is completely empty. + */ + int getMinFilledHeight(); + /** @return The highest y position of a solid block at the given relative chunk position. */ int getSolidHeightMapValue(int xRel, int zRel); /** From 61564d89146b8e70b2bbfca46dcd6aa952766f00 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 11 Sep 2023 07:36:24 -0500 Subject: [PATCH 08/12] Merge branch 'distant-horizons-core-iris.shadow.fix' --- .../core/render/renderer/LodRenderer.java | 16 +++++++++++ .../modAccessor/IIrisAccessor.java | 27 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IIrisAccessor.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 2d9609681..4a1c2da33 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -20,6 +20,7 @@ package com.seibel.distanthorizons.core.render.renderer; import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.ConfigBasedLogger; import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger; @@ -40,6 +41,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering; import com.seibel.distanthorizons.api.enums.rendering.EFogColorMode; import com.seibel.distanthorizons.core.render.fog.LodFogConfig; +import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.distanthorizons.coreapi.util.math.Mat4f; import com.seibel.distanthorizons.coreapi.util.math.Vec3d; import com.seibel.distanthorizons.coreapi.util.math.Vec3f; @@ -62,6 +65,8 @@ public class LodRenderer public static ConfigBasedSpamLogger tickLogger = new ConfigBasedSpamLogger(LogManager.getLogger(LodRenderer.class), () -> Config.Client.Advanced.Logging.logRendererBufferEvent.get(), 1); + private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); + public static final boolean ENABLE_DRAW_LAG_SPIKE_LOGGING = false; public static final boolean ENABLE_DUMP_GL_STATE = true; public static final long DRAW_LAG_SPIKE_THRESHOLD_NS = TimeUnit.NANOSECONDS.convert(20, TimeUnit.MILLISECONDS); @@ -182,6 +187,17 @@ public class LodRenderer return; } + if (IRIS_ACCESSOR != null && IRIS_ACCESSOR.isRenderingShadowPass()) + { + // We do not have a wy to properly render shader shadow pass, since they can + // and often do change the projection entirely, as well as the output usage. + + //EVENT_LOGGER.debug("Skipping shadow pass render."); + return; + } + + + try { // get MC's shader program and save MC's render state so we can restore it later diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IIrisAccessor.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IIrisAccessor.java new file mode 100644 index 000000000..99f96be6e --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IIrisAccessor.java @@ -0,0 +1,27 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor; + +public interface IIrisAccessor extends IModAccessor +{ + boolean isShaderPackInUse(); + + boolean isRenderingShadowPass(); +} From a28eddc1d55ea1afac999f41571266815ecc9501 Mon Sep 17 00:00:00 2001 From: Builderb0y Date: Mon, 11 Sep 2023 16:55:52 +0000 Subject: [PATCH 09/12] remove iteration over chunkArray, calculate index directly instead. --- .../core/generation/DhLightingEngine.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 09329c779..468285b13 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -307,37 +307,37 @@ public class DhLightingEngine /** holds the adjacent chunks without having to create new Pos objects */ private static class AdjacentChunkHolder { - ArrayList chunkArray = new ArrayList<>(9); - + final IChunkWrapper[] chunkArray = new IChunkWrapper[9]; public AdjacentChunkHolder(IChunkWrapper centerWrapper) { this.chunkArray.add(centerWrapper); } - - public int size() { return this.chunkArray.size(); } - - public void add(IChunkWrapper centerWrapper) { this.chunkArray.add(centerWrapper); } - + public void add(IChunkWrapper centerWrapper) { + DhChunkPos centerPos = this.chunkArray[4].getChunkPos(); + DhChunkPos offsetPos = centerWrapper.getChunkPos(); + int offsetX = offsetPos.x - centerPos.x; + if (offsetX < -1 || offsetX > 1) return; + int offsetZ = offsetPos.z - centerPos.z; + if (offsetZ < -1 || offsetZ > 1) return; + //equivalent to 4 + offsetX + (offsetZ * 3). + this.chunkArray[4 + offsetX + offsetZ + (offsetZ << 1)] = centerWrapper; + } + public IChunkWrapper getByBlockPos(int blockX, int blockZ) { - // >> 4 is equivalent to dividing by 16 int chunkX = blockX >> 4; int chunkZ = blockZ >> 4; - - // since there will only ever be 9 items in the array, this sequential search should be fast enough - for (int i = 0; i < this.chunkArray.size(); i++) // using iterators in high traffic areas can cause GC issues due to allocating a bunch of iterators, use an indexed for-loop instead - { - IChunkWrapper chunk = this.chunkArray.get(i); - - if (chunk != null - && chunk.getChunkPos().x == chunkX && chunk.getChunkPos().z == chunkZ) - { - return chunk; - } - } - return null; + IChunkWrapper centerChunk = this.chunkArray[4]; + DhChunkPos centerPos = centerChunk.getChunkPos(); + if (centerPos.x == chunkX && centerPos.z == chunkZ) return centerChunk; + int offsetX = chunkX - centerPos.x; + if (offsetX < -1 || offsetX > 1) return null; + int offsetZ = chunkZ - centerPos.z; + if (offsetZ < -1 || offsetZ > 1) return null; + //equivalent to 4 + offsetX + (offsetZ * 3). + return this.chunkArray[4 + offsetX + offsetZ + (offsetZ << 1)]; } } From a51bb760d0a31f7c19796b5fa03b9e84eb059689 Mon Sep 17 00:00:00 2001 From: Builderb0y Date: Mon, 11 Sep 2023 17:04:17 +0000 Subject: [PATCH 10/12] inline LightPos, effectively preventing tens of thousands of them from being allocated. --- .../core/generation/DhLightingEngine.java | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 468285b13..30bfecd39 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -31,6 +31,8 @@ import org.apache.logging.log4j.Logger; import java.util.*; import java.util.concurrent.locks.ReentrantLock; +import it.unimi.dsi.fastutil.ints.IntArrayList; + /** * This logic was roughly based on * Starlight's technical documentation @@ -171,16 +173,7 @@ public class DhLightingEngine break; } } - - // validate that at least 1 chunk was found - if (adjacentChunkHolder.size() == 0) - { - LOGGER.warn("Attempted to generate lighting for position [" + centerChunkPos + "], but neither that chunk nor any adjacent chunks were found. No chunk lighting was performed."); - return; - } - - - + // block light this.propagateLightPosList(blockLightPosQueue, adjacentChunkHolder, (neighbourChunk, relBlockPos) -> neighbourChunk.getDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z), @@ -214,6 +207,7 @@ public class DhLightingEngine { // these objects are saved so they can be mutated throughout the method, // this reduces the number of allocations necessary, reducing GC pressure + final LightPos lightPos = new LightPos(0, 0, 0, 0); final DhBlockPos neighbourBlockPos = PRIMARY_BLOCK_POS_REF.get(); final DhBlockPos relNeighbourBlockPos = SECONDARY_BLOCK_POS_REF.get(); @@ -223,16 +217,15 @@ public class DhLightingEngine { // since we don't care about the order the positions are processed, // we can grab the last position instead of the first for a slight performance increase (this way the array doesn't need to be shifted over every loop) - LightPos lightPos = lightPosQueue.pop(); + lightPosQueue.pop(lightPos); - DhBlockPos pos = lightPos.pos; int lightValue = lightPos.lightValue; // propagate the lighting in each cardinal direction, IE: -x, +x, -y, +y, -z, +z for (EDhDirection direction : EDhDirection.CARDINAL_DIRECTIONS) // since this is an array instead of an ArrayList this advanced for-loop shouldn't cause any GC issues { - pos.mutateOffset(direction, neighbourBlockPos); + lightPos.mutateOffset(direction, neighbourBlockPos); neighbourBlockPos.mutateToChunkRelativePos(relNeighbourBlockPos); @@ -291,14 +284,13 @@ public class DhLightingEngine @FunctionalInterface interface ISetLightFunc { void setLight(IChunkWrapper chunk, DhBlockPos pos, int lightValue); } - private static class LightPos + private static class LightPos extends DhBlockPos { - public final DhBlockPos pos; public int lightValue; - public LightPos(DhBlockPos pos, int lightValue) + public LightPos(int x, int y, int z, int lightValue) { - this.pos = pos; + super(x, y, z); this.lightValue = lightValue; } @@ -354,10 +346,12 @@ public class DhLightingEngine /** the index of the last item in the array, -1 if empty */ private int index = -1; + + public static final int INTS_PER_LIGHT_POS = 4; //x, y, z, and lightValue. // when tested with a normal 1.20 world James saw a maximum of 36,709 block and 2,355 sky lights, // so this should give us a good base that should be able to contain most lighting tasks - private final ArrayList arrayList = new ArrayList<>(40_000); + private final IntArrayList lightPositions = new IntArrayList(40_000 * INTS_PER_LIGHT_POS); @@ -410,31 +404,36 @@ public class DhLightingEngine public void push(int blockX, int blockY, int blockZ, int lightValue) { this.index++; - if (this.index < this.arrayList.size()) + int start = this.index * INTS_PER_LIGHT_POS; + if (start < this.lightPositions.size()) { - // modify the existing pos in the array - LightPos lightPos = this.arrayList.get(this.index); - lightPos.pos.x = blockX; - lightPos.pos.y = blockY; - lightPos.pos.z = blockZ; - lightPos.lightValue = lightValue; + this.lightPositions.set(start, blockX); + this.lightPositions.set(start + 1, blockY); + this.lightPositions.set(start + 2, blockZ); + this.lightPositions.set(start + 3, lightValue); } else { // add a new pos - this.arrayList.add(new LightPos(new DhBlockPos(blockX, blockY, blockZ), lightValue)); + this.lightPositions.add(blockX); + this.lightPositions.add(blockY); + this.lightPositions.add(blockZ); + this.lightPositions.add(lightValue); } } - public LightPos pop() + public void pop(LightPos pos) { - LightPos pos = this.arrayList.get(this.index); + int start = this.index * INTS_PER_LIGHT_POS; + pos.x = this.lightPositions.getInt(start); + pos.y = this.lightPositions.getInt(start + 1); + pos.z = this.lightPositions.getInt(start + 2); + pos.lightValue = this.lightPositions.getInt(start + 3); this.index--; - return pos; } @Override - public String toString() { return this.index + "/" + this.arrayList.size(); } + public String toString() { return this.index + "/" + (this.arrayList.size() / INTS_PER_LIGHT_POS); } } From 62e8bea246418e569f0d1f352561bbc94a6b7944 Mon Sep 17 00:00:00 2001 From: Builderb0y Date: Tue, 12 Sep 2023 01:05:27 +0000 Subject: [PATCH 11/12] I forgot a line of code. --- .../distanthorizons/core/generation/DhLightingEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 30bfecd39..fcc205db3 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -303,7 +303,7 @@ public class DhLightingEngine public AdjacentChunkHolder(IChunkWrapper centerWrapper) { - this.chunkArray.add(centerWrapper); + this.chunkArray[4] = centerWrapper; } public void add(IChunkWrapper centerWrapper) { From 13b7a20ff6ce15630ff963fb84a855e9694f79a2 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 11 Sep 2023 20:35:33 -0500 Subject: [PATCH 12/12] DhLightingEngine reformat --- .../core/generation/DhLightingEngine.java | 90 ++++++++++++------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index fcc205db3..bd4c9cf04 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.coreapi.util.BitShiftUtil; import org.apache.logging.log4j.Logger; import java.util.*; @@ -217,7 +218,7 @@ public class DhLightingEngine { // since we don't care about the order the positions are processed, // we can grab the last position instead of the first for a slight performance increase (this way the array doesn't need to be shifted over every loop) - lightPosQueue.pop(lightPos); + lightPosQueue.popMutate(lightPos); int lightValue = lightPos.lightValue; @@ -301,34 +302,55 @@ public class DhLightingEngine { final IChunkWrapper[] chunkArray = new IChunkWrapper[9]; - public AdjacentChunkHolder(IChunkWrapper centerWrapper) - { - this.chunkArray[4] = centerWrapper; - } - public void add(IChunkWrapper centerWrapper) { + public AdjacentChunkHolder(IChunkWrapper centerWrapper) { this.chunkArray[4] = centerWrapper; } + + + public void add(IChunkWrapper centerWrapper) + { DhChunkPos centerPos = this.chunkArray[4].getChunkPos(); DhChunkPos offsetPos = centerWrapper.getChunkPos(); + int offsetX = offsetPos.x - centerPos.x; - if (offsetX < -1 || offsetX > 1) return; + if (offsetX < -1 || offsetX > 1) + { + return; + } + int offsetZ = offsetPos.z - centerPos.z; - if (offsetZ < -1 || offsetZ > 1) return; - //equivalent to 4 + offsetX + (offsetZ * 3). + if (offsetZ < -1 || offsetZ > 1) + { + return; + } + + // equivalent to 4 + offsetX + (offsetZ * 3). this.chunkArray[4 + offsetX + offsetZ + (offsetZ << 1)] = centerWrapper; } public IChunkWrapper getByBlockPos(int blockX, int blockZ) { - int chunkX = blockX >> 4; - int chunkZ = blockZ >> 4; + int chunkX = BitShiftUtil.divideByPowerOfTwo(blockX, 4); + int chunkZ = BitShiftUtil.divideByPowerOfTwo(blockZ, 4); IChunkWrapper centerChunk = this.chunkArray[4]; DhChunkPos centerPos = centerChunk.getChunkPos(); - if (centerPos.x == chunkX && centerPos.z == chunkZ) return centerChunk; + if (centerPos.x == chunkX && centerPos.z == chunkZ) + { + return centerChunk; + } + int offsetX = chunkX - centerPos.x; - if (offsetX < -1 || offsetX > 1) return null; + if (offsetX < -1 || offsetX > 1) + { + return null; + } + int offsetZ = chunkZ - centerPos.z; - if (offsetZ < -1 || offsetZ > 1) return null; - //equivalent to 4 + offsetX + (offsetZ * 3). + if (offsetZ < -1 || offsetZ > 1) + { + return null; + } + + // equivalent to 4 + offsetX + (offsetZ * 3). return this.chunkArray[4 + offsetX + offsetZ + (offsetZ << 1)]; } } @@ -347,10 +369,13 @@ public class DhLightingEngine /** the index of the last item in the array, -1 if empty */ private int index = -1; - public static final int INTS_PER_LIGHT_POS = 4; //x, y, z, and lightValue. + /** x, y, z, and lightValue. */ + public static final int INTS_PER_LIGHT_POS = 4; - // when tested with a normal 1.20 world James saw a maximum of 36,709 block and 2,355 sky lights, - // so this should give us a good base that should be able to contain most lighting tasks + /** + * When tested with a normal 1.20 world James saw a maximum of 36,709 block and 2,355 sky lights, + * so 40,000 should be a good starting point that can contain most lighting tasks. + */ private final IntArrayList lightPositions = new IntArrayList(40_000 * INTS_PER_LIGHT_POS); @@ -404,13 +429,13 @@ public class DhLightingEngine public void push(int blockX, int blockY, int blockZ, int lightValue) { this.index++; - int start = this.index * INTS_PER_LIGHT_POS; - if (start < this.lightPositions.size()) + int subIndex = this.index * INTS_PER_LIGHT_POS; + if (subIndex < this.lightPositions.size()) { - this.lightPositions.set(start, blockX); - this.lightPositions.set(start + 1, blockY); - this.lightPositions.set(start + 2, blockZ); - this.lightPositions.set(start + 3, lightValue); + this.lightPositions.set(subIndex, blockX); + this.lightPositions.set(subIndex + 1, blockY); + this.lightPositions.set(subIndex + 2, blockZ); + this.lightPositions.set(subIndex + 3, lightValue); } else { @@ -422,18 +447,21 @@ public class DhLightingEngine } } - public void pop(LightPos pos) + /** mutates the given {@link LightPos} to match the next {@link LightPos} in the queue. */ + public void popMutate(LightPos pos) { - int start = this.index * INTS_PER_LIGHT_POS; - pos.x = this.lightPositions.getInt(start); - pos.y = this.lightPositions.getInt(start + 1); - pos.z = this.lightPositions.getInt(start + 2); - pos.lightValue = this.lightPositions.getInt(start + 3); + int subIndex = this.index * INTS_PER_LIGHT_POS; + + pos.x = this.lightPositions.getInt(subIndex); + pos.y = this.lightPositions.getInt(subIndex + 1); + pos.z = this.lightPositions.getInt(subIndex + 2); + pos.lightValue = this.lightPositions.getInt(subIndex + 3); + this.index--; } @Override - public String toString() { return this.index + "/" + (this.arrayList.size() / INTS_PER_LIGHT_POS); } + public String toString() { return this.index + "/" + (this.lightPositions.size() / INTS_PER_LIGHT_POS); } }