diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java index 3e05ff439..aad26f415 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java @@ -146,7 +146,10 @@ public class ShaderProgram public int getUniformLocation(CharSequence name) { int i = GL32.glGetUniformLocation(id, name); - if (i==-1) throw new RuntimeException("Uniform name not found: "+name); + if (i==-1) + { + throw new RuntimeException("Uniform name not found: "+name); + } return i; } 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 d97df5d9c..77c1e6c81 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 @@ -76,9 +76,9 @@ public class LodRenderer { Vec3d cam = MC_RENDER.getCameraExactPosition(); Vec3f modelPos = new Vec3f((float) (pos.x - cam.x), (float) (pos.y - cam.y), (float) (pos.z - cam.z)); - + + this.shaderProgram.bind(); this.shaderProgram.setModelPos(modelPos); -// FogShader.INSTANCE.setModelPos(modelPos); } public void drawVbo(GLVertexBuffer vbo) @@ -152,37 +152,40 @@ public class LodRenderer EVENT_LOGGER.error("drawLODs() called after close()!"); return; } - + + // get MC's shader program // Save all MC render state LagSpikeCatcher drawSaveGLState = new LagSpikeCatcher(); GLState currentState = new GLState(); - if (ENABLE_DUMP_GL_STATE) + if (ENABLE_DUMP_GL_STATE) { tickLogger.debug("Saving GL state: {}", currentState); } drawSaveGLState.end("drawSaveGLState"); - + GLProxy glProxy = GLProxy.getInstance(); + + //===================// // draw params setup // //===================// - + profiler.push("LOD draw setup"); /*---------Set GL State--------*/ // Make sure to unbind current VBO so we don't mess up vanilla settings //GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer()); - GL32.glViewport(0,0, MC_RENDER.getTargetFrameBufferViewportWidth(), MC_RENDER.getTargetFrameBufferViewportHeight()); + GL32.glViewport(0, 0, MC_RENDER.getTargetFrameBufferViewportWidth(), MC_RENDER.getTargetFrameBufferViewportHeight()); GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0); // set the required open GL settings boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get(); - if (renderWireframe) + if (renderWireframe) { GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); //GL32.glDisable(GL32.GL_CULL_FACE); } - else + else { GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); GL32.glEnable(GL32.GL_CULL_FACE); @@ -190,16 +193,16 @@ public class LodRenderer GL32.glEnable(GL32.GL_DEPTH_TEST); // GL32.glDisable(GL32.GL_DEPTH_TEST); GL32.glDepthFunc(GL32.GL_LESS); - - - + + + transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled; fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled; - + GL32.glDisable(GL32.GL_BLEND); // We render opaque first, then transparent GL32.glDepthMask(true); GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT); - + /*---------Bind required objects--------*/ // Setup LodRenderProgram and the LightmapTexture if it has not yet been done // also binds LightmapTexture, VAO, and ShaderProgram @@ -207,20 +210,19 @@ public class LodRenderer { this.setup(); } - else + else { LodFogConfig newConfig = this.shaderProgram.isShaderUsable(); - if (newConfig != null) + if (newConfig != null) { this.shaderProgram.free(); this.shaderProgram = new LodRenderProgram(newConfig); -// FogShader.INSTANCE.free(); -// FogShader.INSTANCE = new FogShader(newConfig); + FogShader.INSTANCE.free(); + FogShader.INSTANCE = new FogShader(newConfig); } this.shaderProgram.bind(); } GL32.glActiveTexture(GL32.GL_TEXTURE0); - //LightmapTexture lightmapTexture = new LightmapTexture(); /*---------Get required data--------*/ int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; @@ -232,7 +234,7 @@ public class LodRenderer MC_RENDER.isFogStateSpecial() ? this.getSpecialFogColor(partialTicks) : this.getFogColor(partialTicks), 0, MC.getWrappedClientWorld().getHeight(), MC.getWrappedClientWorld().getMinHeight(), RenderUtil.getFarClipPlaneDistanceInBlocks(), vanillaBlockRenderedDistance, MC_RENDER.isFogStateSpecial()); - + // Note: Since lightmapTexture is changing every frame, it's faster to recreate it than to reuse the old one. ILightMapWrapper lightmap = MC_RENDER.getLightmapWrapper(); lightmap.bind(); @@ -242,48 +244,47 @@ public class LodRenderer } this.bufferHandler.buildRenderListAndUpdateSections(this.getLookVector()); - + //===========// // rendering // //===========// profiler.popPush("LOD draw"); LagSpikeCatcher draw = new LagSpikeCatcher(); - - Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); - DhBlockPos cameraBlockPos = MC_RENDER.getCameraBlockPosition(); - Vec3f cameraDir = MC_RENDER.getLookAtVector(); - + //TODO: Directional culling this.bufferHandler.renderOpaque(this); - - if (Config.Client.Advanced.Graphics.Quality.ssao.get()) + + if (Config.Client.Advanced.Graphics.Quality.ssao.get()) { // broken, causes renderer to crash // TODO remove duplicate SSAO shader -// SSAOShader.INSTANCE.render(partialTicks); // For some reason this looks slightly different :/ + //SSAOShader.INSTANCE.render(partialTicks); // For some reason this looks slightly different :/ SSAORenderer.INSTANCE.render(partialTicks); } { -// FogShader.INSTANCE.render(partialTicks); -// DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker + FogShader.INSTANCE.setModelViewProjectionMatrix(modelViewProjectionMatrix); + FogShader.INSTANCE.render(partialTicks); + + // DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker } - + //======================// // render transparency // //======================// - if (LodRenderer.transparencyEnabled) + if (LodRenderer.transparencyEnabled) { GL32.glEnable(GL32.GL_BLEND); GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); //GL32.glDepthMask(false); // This so that even on incorrect sorting of transparent blocks, it still mostly looks correct this.bufferHandler.renderTransparent(this); GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it... + + FogShader.INSTANCE.render(partialTicks); } - //if (drawCall==0) - // tickLogger.info("DrawCall Count: {}", drawCount); - + + //================// // render cleanup // //================// @@ -295,21 +296,19 @@ public class LodRenderer { this.quadIBO.unbind(); } - + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0); this.shaderProgram.unbind(); - //lightmapTexture.free(); DebugRenderer.INSTANCE.render(modelViewProjectionMatrix); GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT); - + currentState.restore(); drawCleanup.end("LodDrawCleanup"); - + // end of internal LOD profiling profiler.pop(); tickLogger.incLogTries(); - } @@ -386,7 +385,7 @@ public class LodRenderer this.isSetupComplete = false; EVENT_LOGGER.info("Renderer Cleanup Started"); this.shaderProgram.free(); -// FogShader.INSTANCE.free(); + FogShader.INSTANCE.free(); if (this.quadIBO != null) { this.quadIBO.destroy(false); 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 53932bdab..62b9631d6 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 @@ -75,6 +75,7 @@ public abstract class AbstractShaderRenderer { /** 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(); init(); @@ -106,7 +107,8 @@ public abstract class AbstractShaderRenderer { GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); - if (applyShader != null) { + if (applyShader != null) + { applyShader.bind(); this.setApplyShaderUniforms(partialTicks); } 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 13788c5c9..93c6d61dd 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 @@ -11,7 +11,6 @@ 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.coreapi.util.math.Mat4f; -import com.seibel.distanthorizons.coreapi.util.math.Vec3f; import org.lwjgl.opengl.GL32; import java.awt.*; @@ -25,7 +24,7 @@ public class FogShader extends AbstractShaderRenderer // public final int modelOffsetUniform; // public final int worldYOffsetUniform; - public final int gProjUniform; + public final int gModelViewProjectionUniform; public final int gDepthMapUniform; // Fog Uniforms @@ -35,8 +34,11 @@ public class FogShader extends AbstractShaderRenderer public final int nearFogStartUniform; public final int nearFogLengthUniform;; public final int fullFogModeUniform; - - public FogShader(LodFogConfig fogConfig) { + + + + public FogShader(LodFogConfig fogConfig) + { // TODO & Note: This code is a bit jank, so try to make it better later (preferably not using something to process the shader) // This code is just a temp fix so that it looks fine for the time being // and even with the jank soloution, i cannot get it to work @@ -45,11 +47,8 @@ public class FogShader extends AbstractShaderRenderer () -> fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(), "fragColor", new String[] { "vPosition" } )); - -// modelOffsetUniform = this.shader.getUniformLocation("modelOffset"); -// worldYOffsetUniform = this.shader.tryGetUniformLocation("worldYOffset"); - - gProjUniform = this.shader.getUniformLocation("gProj"); + + gModelViewProjectionUniform = this.shader.getUniformLocation("gMvmProj"); gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); // Fog uniforms fogColorUniform = this.shader.getUniformLocation("fogColor"); @@ -64,29 +63,25 @@ public class FogShader extends AbstractShaderRenderer @Override void setVertexAttributes() { va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false)); - }; + } @Override - void setShaderUniforms(float partialTicks) { + void setShaderUniforms(float partialTicks) + { + this.shader.bind(); + int lodDrawDistance = RenderUtil.getFarClipPlaneDistanceInBlocks(); int vanillaDrawDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; -// super.bind(); - vanillaDrawDistance += 32; // Give it a 2 chunk boundary for near fog. + vanillaDrawDistance += 32; // Give it a 2 chunk boundary for near fog. + - - Mat4f perspective = Mat4f.perspective( - (float) MC_RENDER.getFov(partialTicks), - MC_RENDER.getTargetFrameBufferViewportWidth() / (float) MC_RENDER.getTargetFrameBufferViewportHeight(), - RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks), - (float) ((lodDrawDistance + LodUtil.REGION_WIDTH) * Math.sqrt(2))); - - - -// if (worldYOffsetUniform != -1) this.shader.setUniform(worldYOffsetUniform, (float) MC.getWrappedClientWorld().getMinHeight()); - - - this.shader.setUniform(this.shader.getUniformLocation("gProj"), perspective); - GL32.glUniform1i(gDepthMapUniform, 0); + // bind the depth buffer + // FIXME having this texture bound causes rendering issues + GL32.glActiveTexture(GL32.GL_TEXTURE3); + GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); + GL32.glUniform1i(gDepthMapUniform, 3); + + // Fog this.shader.setUniform(fullFogModeUniform, MC_RENDER.isFogStateSpecial() ? 1 : 0); this.shader.setUniform(fogColorUniform, MC_RENDER.isFogStateSpecial() ? getSpecialFogColor(partialTicks) : getFogColor(partialTicks)); @@ -117,7 +112,12 @@ public class FogShader extends AbstractShaderRenderer return MC_RENDER.getSpecialFogColor(partialTicks); } - public void setModelPos(Vec3f modelPos) { -// this.shader.setUniform(modelOffsetUniform, modelPos); - } + public void setModelViewProjectionMatrix(Mat4f combinedModelViewProjectionMatrix) + { + this.shader.bind(); + this.shader.setUniform(gModelViewProjectionUniform, combinedModelViewProjectionMatrix); + this.shader.unbind(); + } + + } diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/shaders/flat_shaded.frag index 99a6b47ec..2da833946 100644 --- a/core/src/main/resources/shaders/flat_shaded.frag +++ b/core/src/main/resources/shaders/flat_shaded.frag @@ -97,7 +97,7 @@ vec3 HSV2RGB(vec3 c) { void main() { fragColor = vertexColor; - + // TODO: Move into its own function instead of in an if statement if (noiseEnabled) { @@ -161,9 +161,6 @@ void main() if (fullFogMode != 0) { fragColor = vec4(fogColor.rgb, 1.0); } else { - // TODO: add a white texture to support Optifine shaders - //vec4 textureColor = texture(texImage, textureCoord); - //fragColor = vertexColor * textureColor; float horizontalDist = length(vertexWorldPos.xz) * fogScale; float heightDist = calculateHeightFogDepth( diff --git a/core/src/main/resources/shaders/fog/fog.frag b/core/src/main/resources/shaders/fog/fog.frag index d19f59906..3c9949130 100644 --- a/core/src/main/resources/shaders/fog/fog.frag +++ b/core/src/main/resources/shaders/fog/fog.frag @@ -1,12 +1,11 @@ in vec2 TexCoord; -//in float vertexYPos; - out vec4 fragColor; uniform sampler2D gDepthMap; -uniform mat4 gProj; +// model view matrix and projection matrix +uniform mat4 gMvmProj; uniform float fogScale; uniform float fogVerticalScale; @@ -68,9 +67,9 @@ vec3 calcViewPosition(vec2 coords) { 1.0 ); - vec4 vs_pos = inverse(gProj) * ndc; - vs_pos.xyz = vs_pos.xyz / vs_pos.w; - return vs_pos.xyz; + vec4 eyeCoord = inverse(gMvmProj) * ndc; + vec3 cameraPos = eyeCoord.xyz / eyeCoord.w; + return cameraPos; } /** @@ -79,37 +78,46 @@ vec3 calcViewPosition(vec2 coords) { * * version: 2023-6-21 */ -void main() { - float vertexYPos = 100f; +void main() +{ + float vertexYPos = 100.0f; vec3 vertexWorldPos = calcViewPosition(TexCoord); - - if (fullFogMode != 0) { - fragColor = vec4(fogColor.r, fogColor.g, fogColor.b, 1.); - } else { + + if (fullFogMode == 1) + { + // render everything with the fog color + fragColor = vec4(fogColor.r, fogColor.g, fogColor.b, 1.0); + } + else if (fullFogMode == 0) + { + // render fog based on distance from the camera + float horizontalDist = length(vertexWorldPos.xz) * fogScale; - float heightDist = calculateHeightFogDepth( - vertexWorldPos.y, vertexYPos) * fogVerticalScale; - float farDist = calculateFarFogDepth(horizontalDist, - length(vertexWorldPos.xyz) * fogScale, nearFogStart); + float heightDist = calculateHeightFogDepth(vertexWorldPos.y, vertexYPos) * fogVerticalScale; + float farDist = calculateFarFogDepth(horizontalDist, length(vertexWorldPos.xyz) * fogScale, nearFogStart); float nearFogThickness = getNearFogThickness(horizontalDist); float farFogThickness = getFarFogThickness(farDist); float heightFogThickness = getHeightFogThickness(heightDist); - float mixedFogThickness = clamp(mixFogThickness( - nearFogThickness, farFogThickness, heightFogThickness), 0.0, 1.0); + float mixedFogThickness = + clamp( + mixFogThickness(nearFogThickness, farFogThickness, heightFogThickness) + , 0.0, 1.0); fragColor = vec4(fogColor.r, fogColor.g, fogColor.b, mixedFogThickness); } - - // Testing -// if (fragColor.r != 6969.) { // This line is so that the compiler doesnt delete the previos code -// fragColor = vec4( -// mod(texture(gDepthMap, TexCoord).x, 1), -// mod(texture(gDepthMap, TexCoord).y, 1), -// mod(texture(gDepthMap, TexCoord).z, 1), -// 1. -// ); -// } + else + { + // test code. + + // this can be fired by manually changing the fullFogMode to a (normally) + // invalid value (like 7). By having a separate if statement defined by + // a uniform we don't have to worry about GLSL optimizing away different + // options when testing, causing a bunch of headaches if we just want to render the screen red. + + float depthValue = texture(gDepthMap, TexCoord).r; + fragColor = vec4(vec3(depthValue), 1.0); // Convert depth value to grayscale color + } }