From e93562569bb21d01e2ee046acbc487d81088223e Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 9 Feb 2021 21:18:05 -0800 Subject: [PATCH] world fog works, fluid fog still doesn't. better dimension changes. --- .../com/simibubi/create/events/ClientEvents.java | 16 ++++++++++++---- .../foundation/mixin/RenderInLayerMixin.java | 4 ++-- .../foundation/render/FastRenderDispatcher.java | 11 ++++++----- .../contraption/ContraptionRenderDispatcher.java | 7 ++++--- .../foundation/render/gl/BasicProgram.java | 16 ++++++++++++++-- .../create/foundation/render/gl/GlFog.java | 13 +++++++++++++ .../foundation/render/gl/backend/Backend.java | 2 +- .../render/instancing/InstancedTileRenderer.java | 8 ++++---- .../render/instancing/RenderMaterial.java | 8 ++++---- .../resources/assets/create/shader/belt.vert | 3 +++ .../assets/create/shader/contraption.frag | 12 +++++++++++- .../assets/create/shader/contraption_actor.vert | 3 +++ .../create/shader/contraption_structure.vert | 4 ++++ .../assets/create/shader/instanced.frag | 12 +++++++++++- .../resources/assets/create/shader/rotating.vert | 4 ++++ 15 files changed, 96 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/render/gl/GlFog.java diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 734babaf8..229f4431e 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -39,11 +39,13 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.world.ClientWorld; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.IFluidState; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.ITextComponent; +import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.EntityViewRenderEvent; @@ -112,14 +114,20 @@ public class ClientEvents { @SubscribeEvent public static void onLoadWorld(WorldEvent.Load event) { - CreateClient.invalidateRenderers(); - AnimationTickHolder.reset(); + IWorld world = event.getWorld(); + if (world.isRemote() && world instanceof ClientWorld) { + CreateClient.invalidateRenderers(); + AnimationTickHolder.reset(); + ((ClientWorld) world).loadedTileEntityList.forEach(CreateClient.kineticRenderer::add); + } } @SubscribeEvent public static void onUnloadWorld(WorldEvent.Unload event) { - CreateClient.invalidateRenderers(); - AnimationTickHolder.reset(); + if (event.getWorld().isRemote()) { + CreateClient.invalidateRenderers(); + AnimationTickHolder.reset(); + } } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java index 171943f5c..ba05ba4e1 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java @@ -20,8 +20,8 @@ public class RenderInLayerMixin { * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. * This should probably be a forge event. */ - @Inject(at = @At("TAIL"), method = "renderLayer") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;endSection()V", ordinal = 1), method = "renderLayer") private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { - FastRenderDispatcher.renderLayer(type, stack, cameraX, cameraY, cameraZ); + FastRenderDispatcher.renderLayer(type, stack, (float) cameraX, (float) cameraY, (float) cameraZ); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index 0d7be045d..47649940f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -96,10 +96,10 @@ public class FastRenderDispatcher { } } - public static void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ) { + public static void renderLayer(RenderType type, MatrixStack stack, float cameraX, float cameraY, float cameraZ) { if (!available()) return; - Matrix4f viewProjection = Matrix4f.translate((float) -cameraX, (float) -cameraY, (float) -cameraZ); + Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ); viewProjection.multiplyBackward(stack.peek().getModel()); viewProjection.multiplyBackward(getProjectionMatrix()); @@ -108,12 +108,13 @@ public class FastRenderDispatcher { RenderSystem.enableDepthTest(); RenderSystem.enableCull(); GL11.glCullFace(GL11.GL_BACK); - CreateClient.kineticRenderer.render(type, viewProjection); + CreateClient.kineticRenderer.render(type, viewProjection, cameraX, cameraY, cameraZ); RenderSystem.disableCull(); //RenderSystem.disableDepthTest(); - ContraptionRenderDispatcher.renderLayer(type, viewProjection); - GL20.glUseProgram(0); + ContraptionRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ); + if (!OptifineHandler.usingShaders()) + GL20.glUseProgram(0); type.endDrawing(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java index b10d7ab85..4e5b28149 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.render.contraption; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; @@ -86,7 +87,7 @@ public class ContraptionRenderDispatcher { return renderer; } - public static void renderLayer(RenderType layer, Matrix4f viewProjection) { + public static void renderLayer(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ) { removeDeadContraptions(); if (renderers.isEmpty()) return; @@ -96,13 +97,13 @@ public class ContraptionRenderDispatcher { GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 ContraptionProgram structureShader = Backend.getProgram(AllProgramSpecs.CONTRAPTION_STRUCTURE); - structureShader.bind(viewProjection, FastRenderDispatcher.getDebugMode()); + structureShader.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode()); for (RenderedContraption renderer : renderers.values()) { renderer.doRenderLayer(layer, structureShader); } for (RenderedContraption renderer : renderers.values()) { - renderer.kinetics.render(layer, viewProjection, renderer::setup); + renderer.kinetics.render(layer, viewProjection, camX, camY, camZ, renderer::setup); renderer.teardown(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java b/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java index b39fff2b7..904e4c37e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java @@ -12,6 +12,9 @@ public class BasicProgram extends GlProgram { protected final int uTime; protected final int uViewProjection; protected final int uDebug; + protected final int uCameraPos; + protected final int uFogRange; + protected final int uFogColor; protected int uBlockAtlas; protected int uLightMap; @@ -22,6 +25,9 @@ public class BasicProgram extends GlProgram { uTime = getUniformLocation("uTime"); uViewProjection = getUniformLocation("uViewProjection"); uDebug = getUniformLocation("uDebug"); + uCameraPos = getUniformLocation("uCameraPos"); + uFogRange = getUniformLocation("uFogRange"); + uFogColor = getUniformLocation("uFogColor"); bind(); registerSamplers(); @@ -33,13 +39,19 @@ public class BasicProgram extends GlProgram { uLightMap = setSamplerBinding("uLightMap", 2); } - public void bind(Matrix4f viewProjection, int debugMode) { + public void bind(Matrix4f viewProjection, float camX, float camY, float camZ, int debugMode) { super.bind(); + GL20.glUniform1i(uDebug, debugMode); GL20.glUniform1i(uTicks, AnimationTickHolder.getTicks()); GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick()); + uploadMatrixUniform(uViewProjection, viewProjection); - GL20.glUniform1i(uDebug, debugMode); + GL20.glUniform3f(uCameraPos, camX, camY, camZ); + + GL20.glUniform2f(uFogRange, GlFog.getFogStart(), GlFog.getFogEnd()); + GL20.glGetFloatv(GL20.GL_FOG_COLOR, Backend.VEC4_BUFFER); + GL20.glUniform4fv(uFogColor, Backend.VEC4_BUFFER); } protected static void uploadMatrixUniform(int uniform, Matrix4f mat) { diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/GlFog.java b/src/main/java/com/simibubi/create/foundation/render/gl/GlFog.java new file mode 100644 index 000000000..d13ae540c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/gl/GlFog.java @@ -0,0 +1,13 @@ +package com.simibubi.create.foundation.render.gl; + +import org.lwjgl.opengl.GL20; + +public class GlFog { + public static float getFogEnd() { + return GL20.glGetFloat(GL20.GL_FOG_END); + } + + public static float getFogStart() { + return GL20.glGetFloat(GL20.GL_FOG_START); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java index 4e47f8429..36b198ad6 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java @@ -33,7 +33,7 @@ import java.util.function.Predicate; public class Backend { public static final Logger log = LogManager.getLogger(Backend.class); public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1); // TODO: these leak 80 bytes of memory per program launch - public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3); + public static final FloatBuffer VEC4_BUFFER = MemoryUtil.memAllocFloat(4); public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16); private static final Map> registry = new HashMap<>(); diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java index 03908fb4d..bce27b736 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java @@ -108,14 +108,14 @@ public abstract class InstancedTileRenderer

{ instances.clear(); } - public void render(RenderType layer, Matrix4f viewProjection) { - render(layer, viewProjection, null); + public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ) { + render(layer, viewProjection, camX, camY, camZ, null); } - public void render(RenderType layer, Matrix4f viewProjection, ShaderCallback

callback) { + public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ, ShaderCallback

callback) { for (RenderMaterial material : materials.values()) { if (material.canRenderInLayer(layer)) - material.render(layer, viewProjection, callback); + material.render(layer, viewProjection, camX, camY, camZ, callback); } GL20.glUseProgram(0); diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java index 11e8aebae..d20e61d4e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java @@ -59,13 +59,13 @@ public class RenderMaterial

setup) { + public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ, ShaderCallback

setup) { P program = Backend.getProgram(programSpec); - program.bind(viewProjection, FastRenderDispatcher.getDebugMode()); + program.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode()); if (setup != null) setup.call(program); diff --git a/src/main/resources/assets/create/shader/belt.vert b/src/main/resources/assets/create/shader/belt.vert index 25bb34fd1..a6e5ecc06 100644 --- a/src/main/resources/assets/create/shader/belt.vert +++ b/src/main/resources/assets/create/shader/belt.vert @@ -33,6 +33,8 @@ uniform float uTime; uniform mat4 uViewProjection; uniform int uDebug; +uniform vec3 uCameraPos; +out float FragDistance; mat4 rotate(vec3 axis, float angle) { float s = sin(angle); @@ -83,6 +85,7 @@ void main() { Diffuse = diffuse(norm); TexCoords = aTexCoords - sourceTexture + scrollTexture.xy + vec2(0, scroll); Light = light; + FragDistance = length(worldPos.xyz - uCameraPos); gl_Position = uViewProjection * worldPos; #ifdef CONTRAPTION diff --git a/src/main/resources/assets/create/shader/contraption.frag b/src/main/resources/assets/create/shader/contraption.frag index 8628a2d1f..0cad9b4db 100644 --- a/src/main/resources/assets/create/shader/contraption.frag +++ b/src/main/resources/assets/create/shader/contraption.frag @@ -4,11 +4,15 @@ in vec2 TexCoords; in vec4 Color; in float Diffuse; in vec2 Light; +in float FragDistance; in vec3 BoxCoord; out vec4 fragColor; +uniform vec2 uFogRange; +uniform vec4 uFogColor; + uniform sampler2D uBlockAtlas; uniform sampler2D uLightMap; uniform sampler3D uLightVolume; @@ -21,5 +25,11 @@ vec4 light() { void main() { vec4 tex = texture2D(uBlockAtlas, TexCoords); - fragColor = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a); + vec4 color = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a); + + float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x); + fog = clamp(fog, 0, 1); + + fragColor = mix(uFogColor, color, fog); + fragColor.a = color.a; } \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/contraption_actor.vert b/src/main/resources/assets/create/shader/contraption_actor.vert index f5d4f25ce..de91f6143 100644 --- a/src/main/resources/assets/create/shader/contraption_actor.vert +++ b/src/main/resources/assets/create/shader/contraption_actor.vert @@ -31,6 +31,8 @@ uniform float uTime; uniform mat4 uViewProjection; uniform int uDebug; +uniform vec3 uCameraPos; +out float FragDistance; mat4 rotate(vec3 axis, float angle) { float s = sin(angle); @@ -79,6 +81,7 @@ void main() { Diffuse = diffuse(norm); TexCoords = aTexCoords; Light = modelLight; + FragDistance = length(worldPos.xyz - uCameraPos); gl_Position = uViewProjection * worldPos; if (uDebug == 2) { diff --git a/src/main/resources/assets/create/shader/contraption_structure.vert b/src/main/resources/assets/create/shader/contraption_structure.vert index c88226023..64a2a3759 100644 --- a/src/main/resources/assets/create/shader/contraption_structure.vert +++ b/src/main/resources/assets/create/shader/contraption_structure.vert @@ -22,6 +22,9 @@ uniform float uTime; uniform mat4 uViewProjection; uniform int uDebug; +uniform vec3 uCameraPos; +out float FragDistance; + mat4 rotate(vec3 axis, float angle) { float s = sin(angle); float c = cos(angle); @@ -50,6 +53,7 @@ void main() { Color = aColor / diffuse(aNormal); TexCoords = aTexCoords; Light = modelLight; + FragDistance = length(worldPos.xyz - uCameraPos); gl_Position = uViewProjection * worldPos; if (uDebug == 2) { diff --git a/src/main/resources/assets/create/shader/instanced.frag b/src/main/resources/assets/create/shader/instanced.frag index 626c0d055..0a0aca7cd 100644 --- a/src/main/resources/assets/create/shader/instanced.frag +++ b/src/main/resources/assets/create/shader/instanced.frag @@ -4,9 +4,13 @@ in vec2 TexCoords; in vec2 Light; in float Diffuse; in vec4 Color; +in float FragDistance; out vec4 fragColor; +uniform vec2 uFogRange; +uniform vec4 uFogColor; + uniform sampler2D uBlockAtlas; uniform sampler2D uLightMap; @@ -18,5 +22,11 @@ vec4 light() { void main() { vec4 tex = texture2D(uBlockAtlas, TexCoords); - fragColor = vec4(tex.rgb * light().rgb * Diffuse, tex.a) * Color; + vec4 color = vec4(tex.rgb * light().rgb * Diffuse, tex.a) * Color; + + float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x); + fog = clamp(fog, 0, 1); + + fragColor = mix(uFogColor, color, fog); + fragColor.a = color.a; } \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/rotating.vert b/src/main/resources/assets/create/shader/rotating.vert index f87dc02b4..89b76d975 100644 --- a/src/main/resources/assets/create/shader/rotating.vert +++ b/src/main/resources/assets/create/shader/rotating.vert @@ -29,6 +29,9 @@ uniform float uTime; uniform mat4 uViewProjection; uniform int uDebug; +uniform vec3 uCameraPos; +out float FragDistance; + mat4 rotate(vec3 axis, float angle) { float s = sin(angle); float c = cos(angle); @@ -77,6 +80,7 @@ void main() { Diffuse = diffuse(norm); TexCoords = aTexCoords; Light = light; + FragDistance = length(worldPos.xyz - uCameraPos); gl_Position = uViewProjection * worldPos; #ifdef CONTRAPTION