From db7913d91b3435c1b9b4c5ecdf9b130ca74bc32c Mon Sep 17 00:00:00 2001 From: JozsefA Date: Mon, 12 Apr 2021 16:00:13 -0700 Subject: [PATCH] It all works, needs some cleanup --- .../render/ContraptionProgram.java | 2 +- .../simibubi/create/events/ClientEvents.java | 2 + .../foundation/mixin/RenderHooksMixin.java | 10 +- .../mixin/StoreProjectionMatrixMixin.java | 39 ++++- .../foundation/render/AllProgramSpecs.java | 39 +++-- .../foundation/render/KineticRenderer.java | 2 +- .../foundation/render/backend/Backend.java | 8 +- .../render/backend/FastRenderDispatcher.java | 7 - .../render/backend/ShaderLoader.java | 58 +++---- .../backend/{gl => core}/BasicProgram.java | 7 +- .../backend/effects/EffectsHandler.java | 121 +++++++++++++- .../effects/PostProcessingProgram.java | 76 +++++++++ .../backend/effects/ScreenQuadAttributes.java | 38 +++++ .../render/backend/gl/GlBuffer.java | 35 +++-- .../gl/shader/FogSensitiveProgram.java | 59 +++++-- .../render/backend/gl/shader/GlProgram.java | 147 +++++++++--------- .../render/backend/gl/shader/ProgramSpec.java | 64 +++----- .../backend/gl/shader/ShaderSpecLoader.java | 7 + .../backend/gl/shader/SingleProgram.java | 24 +++ .../backend/instancing/InstancedModel.java | 2 +- .../instancing/InstancedTileRenderer.java | 2 +- .../backend/instancing/RenderMaterial.java | 2 +- .../create/flywheel/shaders/chromatic.frag | 59 ++++++- .../create/flywheel/shaders/screen_quad.vert | 20 +++ 24 files changed, 611 insertions(+), 219 deletions(-) rename src/main/java/com/simibubi/create/foundation/render/backend/{gl => core}/BasicProgram.java (85%) create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/effects/PostProcessingProgram.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/effects/ScreenQuadAttributes.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ShaderSpecLoader.java create mode 100644 src/main/resources/assets/create/flywheel/shaders/screen_quad.vert diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionProgram.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionProgram.java index 977593f34..7e0d2750e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionProgram.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionProgram.java @@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re import org.lwjgl.opengl.GL20; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; +import com.simibubi.create.foundation.render.backend.core.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode; import net.minecraft.util.ResourceLocation; diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 88d13aece..d33a3c3bb 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -186,6 +186,8 @@ public class ClientEvents { ms.pop(); RenderWork.runAll(); + + //Backend.effects.render(); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java index da41425e6..2ea27cea7 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java @@ -46,9 +46,9 @@ public class RenderHooksMixin { if (!Backend.available()) return; - Matrix4f viewProjection = stack.peek() - .getModel() - .copy(); + Matrix4f view = stack.peek() + .getModel(); + Matrix4f viewProjection = view.copy(); viewProjection.multiplyBackward(Backend.projectionMatrix); FastRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ); @@ -56,6 +56,10 @@ public class RenderHooksMixin { ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ); GL20.glUseProgram(0); + + if (type == RenderType.getTranslucent()) { + Backend.effects.render(view); + } } @Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render") diff --git a/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java index 7b1d5c7cd..0fe562376 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java @@ -1,19 +1,41 @@ package com.simibubi.create.foundation.mixin; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.render.backend.Backend; +import com.simibubi.create.foundation.render.backend.effects.EffectsHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.util.math.vector.Matrix4f; @Mixin(GameRenderer.class) -public class StoreProjectionMatrixMixin { +public abstract class StoreProjectionMatrixMixin { + + @Shadow + private float cameraZoom; + @Shadow + private float zoomX; + @Shadow + private float zoomY; + + @Shadow + public abstract double getFOVModifier(ActiveRenderInfo p_215311_1_, float p_215311_2_, boolean p_215311_3_); + + @Shadow + @Final + private Minecraft mc; + @Shadow + private float farPlaneDistance; @Unique private boolean shouldCopy = false; @@ -34,4 +56,19 @@ public class StoreProjectionMatrixMixin { shouldCopy = false; } } + + @Inject(method = "getBasicProjectionMatrix", + at = @At("HEAD"), + cancellable = true) + private void overrideNearPlane(ActiveRenderInfo p_228382_1_, float p_228382_2_, boolean p_228382_3_, CallbackInfoReturnable cir) { + MatrixStack matrixstack = new MatrixStack(); + matrixstack.peek().getModel().loadIdentity(); + if (this.cameraZoom != 1.0F) { + matrixstack.translate((double) this.zoomX, (double) (-this.zoomY), 0.0D); + matrixstack.scale(this.cameraZoom, this.cameraZoom, 1.0F); + } + + matrixstack.peek().getModel().multiply(Matrix4f.perspective(this.getFOVModifier(p_228382_1_, p_228382_2_, p_228382_3_), (float) this.mc.getWindow().getFramebufferWidth() / (float) this.mc.getWindow().getFramebufferHeight(), EffectsHandler.getNearPlane(), EffectsHandler.getFarPlane())); + cir.setReturnValue(matrixstack.peek().getModel()); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java index 840732670..8592dbeb4 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java @@ -11,12 +11,15 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; import com.simibubi.create.content.logistics.block.FlapAttributes; import com.simibubi.create.foundation.render.backend.core.BasicAttributes; +import com.simibubi.create.foundation.render.backend.core.BasicProgram; import com.simibubi.create.foundation.render.backend.core.ModelAttributes; import com.simibubi.create.foundation.render.backend.core.OrientedAttributes; import com.simibubi.create.foundation.render.backend.core.TransformAttributes; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; +import com.simibubi.create.foundation.render.backend.effects.PostProcessingProgram; +import com.simibubi.create.foundation.render.backend.gl.shader.FogSensitiveProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; +import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram; import net.minecraft.util.ResourceLocation; @@ -25,7 +28,15 @@ public class AllProgramSpecs { // noop, make sure the static field are loaded. } - public static final ProgramSpec MODEL = register(ProgramSpec.builder("model", BasicProgram::new) + public static final ProgramSpec CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(PostProcessingProgram::new)) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(TransformAttributes.class) + .setVert(Locations.SCREEN_QUAD) + .setFrag(Locations.CHROMATIC) + .createProgramSpec()); + + public static final ProgramSpec MODEL = register(ProgramSpec.builder("model", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(TransformAttributes.class) @@ -33,7 +44,7 @@ public class AllProgramSpecs { .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); - public static final ProgramSpec ORIENTED = register(ProgramSpec.builder("oriented", BasicProgram::new) + public static final ProgramSpec ORIENTED = register(ProgramSpec.builder("oriented", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(OrientedAttributes.class) @@ -41,7 +52,7 @@ public class AllProgramSpecs { .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); - public static final ProgramSpec ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) + public static final ProgramSpec ROTATING = register(ProgramSpec.builder("rotating", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(KineticAttributes.class) @@ -50,7 +61,7 @@ public class AllProgramSpecs { .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); - public static final ProgramSpec BELT = register(ProgramSpec.builder("belt", BasicProgram::new) + public static final ProgramSpec BELT = register(ProgramSpec.builder("belt", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(KineticAttributes.class) @@ -59,18 +70,18 @@ public class AllProgramSpecs { .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); - public static final ProgramSpec FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) + public static final ProgramSpec FLAPS = register(ProgramSpec.builder("flap", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(FlapAttributes.class) .setVert(Locations.FLAP) .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); - public static final ProgramSpec C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) + public static final ProgramSpec C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ContraptionAttributes.class) .setVert(Locations.CONTRAPTION_STRUCTURE) .setFrag(Locations.CONTRAPTION) .createProgramSpec()); - public static final ProgramSpec C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) + public static final ProgramSpec C_MODEL = register(ProgramSpec.builder("contraption_model", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(TransformAttributes.class) @@ -78,7 +89,7 @@ public class AllProgramSpecs { .setFrag(Locations.CONTRAPTION) .setDefines(ShaderConstants.define("CONTRAPTION")) .createProgramSpec()); - public static final ProgramSpec C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", ContraptionProgram::new) + public static final ProgramSpec C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(OrientedAttributes.class) @@ -86,7 +97,7 @@ public class AllProgramSpecs { .setFrag(Locations.CONTRAPTION) .setDefines(ShaderConstants.define("CONTRAPTION")) .createProgramSpec()); - public static final ProgramSpec C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) + public static final ProgramSpec C_ROTATING = register(ProgramSpec.builder("contraption_rotating", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(KineticAttributes.class) @@ -95,7 +106,7 @@ public class AllProgramSpecs { .setFrag(Locations.CONTRAPTION) .setDefines(ShaderConstants.define("CONTRAPTION")) .createProgramSpec()); - public static final ProgramSpec C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) + public static final ProgramSpec C_BELT = register(ProgramSpec.builder("contraption_belt", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(KineticAttributes.class) @@ -104,14 +115,14 @@ public class AllProgramSpecs { .setFrag(Locations.CONTRAPTION) .setDefines(ShaderConstants.define("CONTRAPTION")) .createProgramSpec()); - public static final ProgramSpec C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) + public static final ProgramSpec C_FLAPS = register(ProgramSpec.builder("contraption_flap", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(FlapAttributes.class) .setVert(Locations.FLAP) .setFrag(Locations.CONTRAPTION) .setDefines(ShaderConstants.define("CONTRAPTION")) .createProgramSpec()); - public static final ProgramSpec C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) + public static final ProgramSpec C_ACTOR = register(ProgramSpec.builder("contraption_actor", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(ActorVertexAttributes.class) .setVert(Locations.CONTRAPTION_ACTOR) @@ -120,6 +131,8 @@ public class AllProgramSpecs { public static class Locations { + public static final ResourceLocation SCREEN_QUAD = loc("screen_quad.vert"); + public static final ResourceLocation CHROMATIC = loc("chromatic.frag"); public static final ResourceLocation MODEL_FRAG = loc("model.frag"); public static final ResourceLocation MODEL_VERT = loc("model.vert"); public static final ResourceLocation ORIENTED = loc("oriented.vert"); diff --git a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java index 451122105..d6dd5bb80 100644 --- a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java @@ -7,9 +7,9 @@ import com.simibubi.create.content.contraptions.base.RotatingModel; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.logistics.block.FlapModel; import com.simibubi.create.foundation.render.backend.MaterialTypes; +import com.simibubi.create.foundation.render.backend.core.BasicProgram; import com.simibubi.create.foundation.render.backend.core.OrientedModel; import com.simibubi.create.foundation.render.backend.core.TransformedModel; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java index 9c17503c9..095f96b84 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java @@ -9,7 +9,7 @@ import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.render.backend.gl.GlFog; +import com.simibubi.create.foundation.render.backend.effects.EffectsHandler; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; @@ -28,6 +28,7 @@ public class Backend { public static final Logger log = LogManager.getLogger(Backend.class); public static final ShaderLoader shaderLoader = new ShaderLoader(); + public static EffectsHandler effects; public static Matrix4f projectionMatrix = new Matrix4f(); @@ -108,5 +109,10 @@ public class Backend { compat.instancedArraysSupported(); enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders(); + + if (enabled) { + if (effects != null) effects.delete(); + effects = new EffectsHandler(); + } } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/backend/FastRenderDispatcher.java index f4deae1dc..fd516cdd8 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/FastRenderDispatcher.java @@ -2,24 +2,17 @@ package com.simibubi.create.foundation.render.backend; import java.util.concurrent.ConcurrentHashMap; -import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.foundation.render.KineticRenderer; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.WorldAttached; import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.player.ClientPlayerEntity; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; -import net.minecraft.potion.Effects; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; -import net.minecraft.util.math.vector.Vector3f; import net.minecraft.world.World; public class FastRenderDispatcher { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java b/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java index 41c5dfb33..1683c63bf 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java @@ -12,7 +12,6 @@ import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; import java.util.Collection; -import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -27,11 +26,9 @@ import org.lwjgl.system.MemoryUtil; import com.google.common.collect.Lists; import com.mojang.blaze3d.systems.RenderSystem; -import com.simibubi.create.foundation.render.backend.gl.GlFogMode; -import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.GlShader; -import com.simibubi.create.foundation.render.backend.gl.shader.FogSensitiveProgram; import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; @@ -96,43 +93,34 @@ public class ShaderLoader { private

> void loadProgramFromSpec(S programSpec) { - if (programSpec.fogSensitive) { - Map programGroup = new EnumMap<>(GlFogMode.class); - - for (GlFogMode fogMode : GlFogMode.values()) { - programGroup.put(fogMode, loadProgram(programSpec, fogMode)); - } - - Backend.programs.put(programSpec, new FogSensitiveProgram<>(programGroup)); - } else { - P program = loadProgram(programSpec, GlFogMode.NONE); - - Backend.programs.put(programSpec, new SingleProgram<>(program)); - } + Backend.programs.put(programSpec, programSpec.finalizer.create(this, programSpec)); Backend.log.debug("Loaded program {}", programSpec.name); } - private

> P loadProgram(S programSpec, GlFogMode fogMode) { - GlShader vert = null; - GlShader frag = null; + public GlProgram.Builder loadProgram(ProgramSpec programSpec) { + return loadProgram(programSpec, programSpec.defines); + } + + public GlProgram.Builder loadProgram(ProgramSpec programSpec, ShaderConstants defines) { + return loadProgram(programSpec.name, programSpec.vert, programSpec.frag, programSpec.attributes, defines); + } + + public GlProgram.Builder loadProgram(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, Collection attribs, ShaderConstants defines) { + GlShader vsh = null; + GlShader fsh = null; try { - ShaderConstants defines = new ShaderConstants(programSpec.defines); - - defines.defineAll(fogMode.getDefines()); - - vert = loadShader(programSpec.getVert(), ShaderType.VERTEX, defines); - frag = loadShader(programSpec.getFrag(), ShaderType.FRAGMENT, defines); - - GlProgram.Builder builder = GlProgram.builder(programSpec.name, fogMode).attachShader(vert).attachShader(frag); - - programSpec.attributes.forEach(builder::addAttribute); - - return builder.build(programSpec.factory); + vsh = loadShader(vert, ShaderType.VERTEX, defines); + fsh = loadShader(frag, ShaderType.FRAGMENT, defines); + return GlProgram.builder(name) + .attachShader(vsh) + .attachShader(fsh) + .addAttributes(attribs) + .link(); } finally { - if (vert != null) vert.delete(); - if (frag != null) frag.delete(); + if (vsh != null) vsh.delete(); + if (fsh != null) fsh.delete(); } } @@ -166,7 +154,7 @@ public class ShaderLoader { }); } - private GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { + public GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { String source = shaderSource.get(name); source = processIncludes(name, source); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/core/BasicProgram.java similarity index 85% rename from src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java rename to src/main/java/com/simibubi/create/foundation/render/backend/core/BasicProgram.java index 2087795b0..5f2e671d3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/core/BasicProgram.java @@ -1,8 +1,7 @@ -package com.simibubi.create.foundation.render.backend.gl; +package com.simibubi.create.foundation.render.backend.core; import org.lwjgl.opengl.GL20; -import com.simibubi.create.foundation.render.backend.RenderUtil; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -51,8 +50,4 @@ public class BasicProgram extends GlProgram { fogMode.bind(); } - - protected static void uploadMatrixUniform(int uniform, Matrix4f mat) { - GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat)); - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java index 509e5fb5b..e0bbdaadb 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java @@ -1,24 +1,72 @@ package com.simibubi.create.foundation.render.backend.effects; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; + +import com.simibubi.create.foundation.render.AllProgramSpecs; +import com.simibubi.create.foundation.render.backend.Backend; +import com.simibubi.create.foundation.render.backend.gl.GlBuffer; +import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType; +import com.simibubi.create.foundation.render.backend.gl.GlVertexArray; +import com.simibubi.create.foundation.utility.AnimationTickHolder; + import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.shader.Framebuffer; +import net.minecraft.client.shader.FramebufferConstants; +import net.minecraft.util.math.vector.Matrix4f; +import net.minecraft.util.math.vector.Vector3d; public class EffectsHandler { - final Minecraft mc; + public static float getNearPlane() { + return 0.05f; + } + + public static float getFarPlane() { + return Minecraft.getInstance().gameRenderer.getFarPlaneDistance(); + } + + public static final float[] vertices = { + // pos // tex + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + + private static final int bufferSize = vertices.length * 4; private final Framebuffer framebuffer; + private final GlVertexArray vao = new GlVertexArray(); - public EffectsHandler(Minecraft minecraft) { - this.mc = minecraft; + private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER); - Framebuffer render = minecraft.getFramebuffer(); + public EffectsHandler() { + Framebuffer render = Minecraft.getInstance().getFramebuffer(); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); + + vbo.bind(); + vbo.alloc(bufferSize, GL15.GL_STATIC_DRAW); + vbo.map(bufferSize, buf -> buf.asFloatBuffer().put(vertices)); + + vao.bind(); + + GL20.glEnableVertexAttribArray(0); + + GL20.glVertexAttribPointer(0, 4, GlPrimitiveType.FLOAT.getGlConstant(), false, 4 * 4, 0); + + vao.unbind(); + vbo.unbind(); } public void prepFramebufferSize() { - MainWindow window = mc.getWindow(); + MainWindow window = Minecraft.getInstance().getWindow(); if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) { framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), @@ -26,5 +74,68 @@ public class EffectsHandler { } } + public void render(Matrix4f view) { + GL20.glEnable(GL20.GL_DEPTH_TEST); + GL20.glDepthRange(getNearPlane(), getFarPlane()); + +// float[] floats = new float[2]; +// GL20.glGetFloatv(GL20.GL_DEPTH_RANGE, floats); + + prepFramebufferSize(); + + Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer(); + + GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject); + + PostProcessingProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC); + program.bind(); + + program.bindColorTexture(mainBuffer.getColorAttachment()); + program.bindDepthTexture(mainBuffer.getDepthAttachment()); + + GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; + Matrix4f projection = gameRenderer.getBasicProjectionMatrix(gameRenderer.getActiveRenderInfo(), AnimationTickHolder.getPartialTicks(), true); + //Matrix4f projection = Backend.projectionMatrix.copy(); + //projection.a23 = projection.a32 = 0; + projection.a33 = 1; + projection.invert(); + program.bindInverseProjection(projection); + + Matrix4f inverseView = view.copy(); + inverseView.invert(); +// Matrix4f inverseView = new Matrix4f(); +// inverseView.loadIdentity(); + program.bindInverseView(inverseView); + + Vector3d pos = new Vector3d(286, 73, -149); + Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView(); + + Vector3d shaderPos = pos.subtract(cameraPos).scale(1 / getFarPlane()); + program.setSphere(shaderPos, 20f / getFarPlane(), 0.01f); + + program.setFarPlane(getFarPlane()); + program.setNearPlane(getNearPlane()); + + vao.bind(); + GL20.glDrawArrays(GL20.GL_TRIANGLES, 0, 6); + vao.unbind(); + + program.bindColorTexture(0); + program.bindDepthTexture(0); + + program.unbind(); + + GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject); + GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject); + GL30.glBlitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR); + GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, mainBuffer.framebufferObject); + } + + public void delete() { + framebuffer.deleteFramebuffer(); + + vao.delete(); + vbo.delete(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/PostProcessingProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/PostProcessingProgram.java new file mode 100644 index 000000000..19f239ad2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/PostProcessingProgram.java @@ -0,0 +1,76 @@ +package com.simibubi.create.foundation.render.backend.effects; + +import org.lwjgl.opengl.GL20; + +import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.vector.Matrix4f; +import net.minecraft.util.math.vector.Vector3d; + +public class PostProcessingProgram extends GlProgram { + + final int uDepth; + final int uColor; + + final int uInverseProjection; + final int uInverseView; + + final int uNearPlane; + final int uFarPlane; + final int uSphereCenter; + final int uSphereRadius; + final int uSphereFeather; + + + public PostProcessingProgram(ResourceLocation name, int handle) { + super(name, handle); + + uInverseProjection = getUniformLocation("uInverseProjection"); + uInverseView = getUniformLocation("uInverseView"); + uNearPlane = getUniformLocation("uNearPlane"); + uFarPlane = getUniformLocation("uFarPlane"); + uSphereCenter = getUniformLocation("uSphereCenter"); + uSphereRadius = getUniformLocation("uSphereRadius"); + uSphereFeather = getUniformLocation("uSphereFeather"); + + bind(); + uDepth = setSamplerBinding("uDepth", 8); + uColor = setSamplerBinding("uColor", 9); + unbind(); + } + + public void setNearPlane(float nearPlane) { + GL20.glUniform1f(uNearPlane, nearPlane); + } + + public void setFarPlane(float farPlane) { + GL20.glUniform1f(uFarPlane, farPlane); + } + + public void setSphere(Vector3d center, float radius, float feather) { + GL20.glUniform3f(uSphereCenter, (float) center.x, (float) center.y, (float) center.z); + + GL20.glUniform1f(uSphereRadius, radius); + GL20.glUniform1f(uSphereFeather, feather); + } + + public void bindInverseProjection(Matrix4f mat) { + uploadMatrixUniform(uInverseProjection, mat); + } + + public void bindInverseView(Matrix4f mat) { + uploadMatrixUniform(uInverseView, mat); + } + + public void bindDepthTexture(int textureObject) { + GL20.glActiveTexture(GL20.GL_TEXTURE8); + GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject); + } + + public void bindColorTexture(int textureObject) { + GL20.glActiveTexture(GL20.GL_TEXTURE9); + GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/ScreenQuadAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ScreenQuadAttributes.java new file mode 100644 index 000000000..5b81e2383 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ScreenQuadAttributes.java @@ -0,0 +1,38 @@ +package com.simibubi.create.foundation.render.backend.effects; + +import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; + +public enum ScreenQuadAttributes implements IVertexAttrib { + INSTANCE_POS("aVertex", CommonAttributes.VEC4), + ; + + private final String name; + private final IAttribSpec spec; + + ScreenQuadAttributes(String name, IAttribSpec spec) { + this.name = name; + this.spec = spec; + } + + @Override + public String attribName() { + return name; + } + + @Override + public IAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return 0; + } + + @Override + public int getBufferIndex() { + return 0; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/GlBuffer.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/GlBuffer.java index f39913ccd..7cb688703 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/GlBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/GlBuffer.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.render.backend.gl; import java.nio.ByteBuffer; import java.util.function.Consumer; +import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import com.simibubi.create.foundation.render.backend.Backend; @@ -18,25 +19,29 @@ public class GlBuffer extends GlObject { public int getBufferType() { return bufferType; - } + } - public void bind() { - GL20.glBindBuffer(bufferType, handle()); - } + public void bind() { + GL20.glBindBuffer(bufferType, handle()); + } - public void unbind() { - GL20.glBindBuffer(bufferType, 0); - } + public void unbind() { + GL20.glBindBuffer(bufferType, 0); + } - public void with(Consumer action) { - bind(); - action.accept(this); - unbind(); - } + public void alloc(int size, int usage) { + GL15.glBufferData(bufferType, size, usage); + } - public void map(int length, Consumer upload) { - Backend.compat.mapBuffer(bufferType, 0, length, upload); - } + public void with(Consumer action) { + bind(); + action.accept(this); + unbind(); + } + + public void map(int length, Consumer upload) { + Backend.compat.mapBuffer(bufferType, 0, length, upload); + } public void map(int offset, int length, Consumer upload) { Backend.compat.mapBuffer(bufferType, offset, length, upload); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/FogSensitiveProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/FogSensitiveProgram.java index 426dbc4ac..b308a6bd3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/FogSensitiveProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/FogSensitiveProgram.java @@ -1,26 +1,61 @@ package com.simibubi.create.foundation.render.backend.gl.shader; +import java.util.EnumMap; import java.util.Map; +import com.simibubi.create.foundation.render.backend.ShaderLoader; import com.simibubi.create.foundation.render.backend.gl.GlFog; import com.simibubi.create.foundation.render.backend.gl.GlFogMode; +import net.minecraft.util.ResourceLocation; + public class FogSensitiveProgram

implements IMultiProgram

{ - private final Map programs; + private final Map programs; - public FogSensitiveProgram(Map programs) { - this.programs = programs; - } + public FogSensitiveProgram(Map programs) { + this.programs = programs; + } - @Override - public P get() { - return programs.get(GlFog.getFogMode()); - } + @Override + public P get() { + return programs.get(GlFog.getFogMode()); + } - @Override - public void delete() { - programs.values().forEach(GlProgram::delete); - } + @Override + public void delete() { + programs.values().forEach(GlProgram::delete); + } + public static class SpecLoader

implements ShaderSpecLoader

{ + + private final FogProgramLoader

fogProgramLoader; + + public SpecLoader(FogProgramLoader

fogProgramLoader) { + this.fogProgramLoader = fogProgramLoader; + } + + @Override + public IMultiProgram

create(ShaderLoader loader, ProgramSpec

spec) { + Map programs = new EnumMap<>(GlFogMode.class); + + for (GlFogMode fogMode : GlFogMode.values()) { + ShaderConstants defines = new ShaderConstants(spec.defines); + + defines.defineAll(fogMode.getDefines()); + + GlProgram.Builder builder = loader.loadProgram(spec, defines); + + programs.put(fogMode, fogProgramLoader.create(builder.name, builder.program, fogMode.getFogFactory())); + } + + return new FogSensitiveProgram<>(programs); + } + + } + + public interface FogProgramLoader

{ + + P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java index 56dce3fd8..40d2e62ae 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/GlProgram.java @@ -1,34 +1,37 @@ package com.simibubi.create.foundation.render.backend.gl.shader; +import java.util.Collection; + import org.lwjgl.opengl.GL20; import com.simibubi.create.foundation.render.backend.Backend; -import com.simibubi.create.foundation.render.backend.gl.GlFogMode; +import com.simibubi.create.foundation.render.backend.RenderUtil; import com.simibubi.create.foundation.render.backend.gl.GlObject; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.vector.Matrix4f; public abstract class GlProgram extends GlObject { - public final ResourceLocation name; + public final ResourceLocation name; - protected GlProgram(ResourceLocation name, int handle) { - setHandle(handle); - this.name = name; - } + protected GlProgram(ResourceLocation name, int handle) { + setHandle(handle); + this.name = name; + } - public static Builder builder(ResourceLocation name, GlFogMode fogMode) { - return new Builder(name, fogMode); - } + public static Builder builder(ResourceLocation name) { + return new Builder(name); + } - public void bind() { - GL20.glUseProgram(handle()); - } + public void bind() { + GL20.glUseProgram(handle()); + } - public void unbind() { - GL20.glUseProgram(0); - } + public void unbind() { + GL20.glUseProgram(0); + } /** * Retrieves the index of the uniform with the given name. @@ -52,76 +55,78 @@ public abstract class GlProgram extends GlObject { * @return The sampler uniform's index. * @throws NullPointerException If no uniform exists with the given name. */ - public int setSamplerBinding(String name, int binding) { - int samplerUniform = getUniformLocation(name); + public int setSamplerBinding(String name, int binding) { + int samplerUniform = getUniformLocation(name); - if (samplerUniform >= 0) { - GL20.glUniform1i(samplerUniform, binding); - } + if (samplerUniform >= 0) { + GL20.glUniform1i(samplerUniform, binding); + } - return samplerUniform; - } + return samplerUniform; + } - @Override - protected void deleteInternal(int handle) { - GL20.glDeleteProgram(handle); - } + protected static void uploadMatrixUniform(int uniform, Matrix4f mat) { + GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat)); + } - public static class Builder { - private final ResourceLocation name; - private final int program; - private final GlFogMode fogMode; + @Override + protected void deleteInternal(int handle) { + GL20.glDeleteProgram(handle); + } - private int attributeIndex; + public static class Builder { + public final ResourceLocation name; + public final int program; - public Builder(ResourceLocation name, GlFogMode fogMode) { - this.name = name; - this.program = GL20.glCreateProgram(); - this.fogMode = fogMode; - } + private int attributeIndex; - public Builder attachShader(GlShader shader) { - GL20.glAttachShader(this.program, shader.handle()); + public Builder(ResourceLocation name) { + this.name = name; + this.program = GL20.glCreateProgram(); + } - return this; - } + public Builder attachShader(GlShader shader) { + GL20.glAttachShader(this.program, shader.handle()); - public Builder addAttribute(A attrib) { - GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName()); - attributeIndex += attrib.attribSpec().getAttributeCount(); - return this; - } + return this; + } - /** - * Links the attached shaders to this program and returns a user-defined container which wraps the shader - * program. This container can, for example, provide methods for updating the specific uniforms of that shader - * set. - * - * @param factory The factory which will create the shader program's container - * @param

The type which should be instantiated with the new program's handle - * @return An instantiated shader container as provided by the factory - */ - public

P build(ProgramFactory

factory) { - GL20.glLinkProgram(this.program); + public Builder addAttributes(Collection attributes) { + attributes.forEach(this::addAttribute); + return this; + } - String log = GL20.glGetProgramInfoLog(this.program); + public Builder addAttribute(A attrib) { + GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName()); + attributeIndex += attrib.attribSpec().getAttributeCount(); + return this; + } - if (!log.isEmpty()) { - Backend.log.debug("Program link log for " + this.name + ": " + log); - } + /** + * Links the attached shaders to this program and returns a user-defined container which wraps the shader + * program. This container can, for example, provide methods for updating the specific uniforms of that shader + * set. + * + * @param factory The factory which will create the shader program's container + * @param

The type which should be instantiated with the new program's handle + * @return An instantiated shader container as provided by the factory + */ + public Builder link() { + GL20.glLinkProgram(this.program); - int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS); + String log = GL20.glGetProgramInfoLog(this.program); - if (result != GL20.GL_TRUE) { - throw new RuntimeException("Shader program linking failed, see log for details"); - } + if (!log.isEmpty()) { + Backend.log.debug("Program link log for " + this.name + ": " + log); + } - return factory.create(this.name, this.program, this.fogMode.getFogFactory()); - } - } + int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS); - @FunctionalInterface - public interface ProgramFactory

{ - P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory); - } + if (result != GL20.GL_TRUE) { + throw new RuntimeException("Shader program linking failed, see log for details"); + } + + return this; + } + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ProgramSpec.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ProgramSpec.java index 26c3b0eb2..33c891517 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ProgramSpec.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ProgramSpec.java @@ -16,54 +16,42 @@ public class ProgramSpec

{ public final ShaderConstants defines; - public final GlProgram.ProgramFactory

factory; - public final ArrayList attributes; - public final boolean fogSensitive; + public final ShaderSpecLoader

finalizer; - public static

Builder

builder(String name, GlProgram.ProgramFactory

factory) { - return builder(new ResourceLocation(Create.ID, name), factory); - } - - public static

Builder

builder(ResourceLocation name, GlProgram.ProgramFactory

factory) { - return new Builder<>(name, factory); - } - - public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory

factory, ShaderConstants defines, ArrayList attributes, boolean fogSensitive) { - this.name = name; - this.vert = vert; - this.frag = frag; - this.defines = defines; - - this.factory = factory; - this.attributes = attributes; - this.fogSensitive = fogSensitive; + public static

Builder

builder(String name, ShaderSpecLoader

factory) { + return builder(new ResourceLocation(Create.ID, name), factory); } - public ResourceLocation getVert() { - return vert; - } + public static

Builder

builder(ResourceLocation name, ShaderSpecLoader

factory) { + return new Builder<>(name, factory); + } - public ResourceLocation getFrag() { - return frag; - } + public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList attributes, ShaderSpecLoader

finalizer) { + this.name = name; + this.vert = vert; + this.frag = frag; + this.defines = defines; + + this.attributes = attributes; + this.finalizer = finalizer; + } public static class Builder

{ private ResourceLocation vert; private ResourceLocation frag; - private ShaderConstants defines = ShaderConstants.EMPTY; - private boolean fogSensitive = true; + private ShaderConstants defines = ShaderConstants.EMPTY; + private final ShaderSpecLoader

loader; private final ResourceLocation name; - private final GlProgram.ProgramFactory

factory; private final ArrayList attributes; - public Builder(ResourceLocation name, GlProgram.ProgramFactory

factory) { - this.name = name; - this.factory = factory; - attributes = new ArrayList<>(); - } + public Builder(ResourceLocation name, ShaderSpecLoader

factory) { + this.name = name; + this.loader = factory; + attributes = new ArrayList<>(); + } public Builder

setVert(ResourceLocation vert) { this.vert = vert; @@ -80,18 +68,14 @@ public class ProgramSpec

{ return this; } - public Builder

setFogSensitive(boolean fogSensitive) { - this.fogSensitive = fogSensitive; - return this; - } - public & IVertexAttrib> Builder

addAttributes(Class attributeEnum) { attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants())); return this; } public ProgramSpec

createProgramSpec() { - return new ProgramSpec<>(name, vert, frag, factory, defines, attributes, fogSensitive); + return new ProgramSpec<>(name, vert, frag, defines, attributes, loader); } } + } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ShaderSpecLoader.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ShaderSpecLoader.java new file mode 100644 index 000000000..3747a572c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/ShaderSpecLoader.java @@ -0,0 +1,7 @@ +package com.simibubi.create.foundation.render.backend.gl.shader; + +import com.simibubi.create.foundation.render.backend.ShaderLoader; + +public interface ShaderSpecLoader

{ + IMultiProgram

create(ShaderLoader loader, ProgramSpec

spec); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/SingleProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/SingleProgram.java index c3ee700ab..832e6d8e3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/SingleProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/shader/SingleProgram.java @@ -1,5 +1,9 @@ package com.simibubi.create.foundation.render.backend.gl.shader; +import com.simibubi.create.foundation.render.backend.ShaderLoader; + +import net.minecraft.util.ResourceLocation; + public class SingleProgram

implements IMultiProgram

{ final P program; @@ -16,4 +20,24 @@ public class SingleProgram

implements IMultiProgram

{ public void delete() { program.delete(); } + + public static class SpecLoader

implements ShaderSpecLoader

{ + final ProgramFactory

factory; + + public SpecLoader(ProgramFactory

factory) { + this.factory = factory; + } + + @Override + public IMultiProgram

create(ShaderLoader loader, ProgramSpec

spec) { + GlProgram.Builder builder = loader.loadProgram(spec); + + return new SingleProgram<>(factory.create(builder.name, builder.program)); + } + } + + @FunctionalInterface + public interface ProgramFactory

{ + P create(ResourceLocation name, int handle); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java index fc6be1b40..10f182d46 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java @@ -182,7 +182,7 @@ public abstract class InstancedModel extends BufferedMod int requiredSize = size * stride; if (requiredSize > glBufferSize) { glBufferSize = requiredSize + stride * 16; - GL15.glBufferData(instanceVBO.getBufferType(), glBufferSize, GL15.GL_STATIC_DRAW); + instanceVBO.alloc(glBufferSize, GL15.GL_STATIC_DRAW); instanceVBO.map(glBufferSize, buffer -> { for (D datum : data) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index a7bdc1dcc..fd080bf7d 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -9,9 +9,9 @@ import javax.annotation.Nullable; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.MaterialType; import com.simibubi.create.foundation.render.backend.MaterialTypes; +import com.simibubi.create.foundation.render.backend.core.BasicProgram; import com.simibubi.create.foundation.render.backend.core.ModelData; import com.simibubi.create.foundation.render.backend.core.OrientedData; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java index f2f3e1bc7..a56770802 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java @@ -19,7 +19,7 @@ import com.simibubi.create.foundation.render.Compartment; import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; +import com.simibubi.create.foundation.render.backend.core.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; diff --git a/src/main/resources/assets/create/flywheel/shaders/chromatic.frag b/src/main/resources/assets/create/flywheel/shaders/chromatic.frag index 7a1546907..bd70e8d22 100644 --- a/src/main/resources/assets/create/flywheel/shaders/chromatic.frag +++ b/src/main/resources/assets/create/flywheel/shaders/chromatic.frag @@ -1,13 +1,62 @@ #version 120 -layout (std140) struct Sphere { - vec4 positionRadius; - vec4 color; -} uSpheres; +varying vec4 Vertex; +varying vec3 CameraDir; + +//layout (std140) struct Sphere { +// vec4 positionRadius; +// vec4 color; +//} uSphere; uniform sampler2D uDepth; uniform sampler2D uColor; +uniform mat4 uInverseProjection; +uniform mat4 uInverseView; + +uniform float uNearPlane = 0.15; +uniform float uFarPlane = 1; +uniform vec3 uSphereCenter = vec3(0, 0, 0); +uniform float uSphereRadius = 1; +uniform float uSphereFeather = 0.05; + +float linearizeDepth(float d, float zNear, float zFar) { + float z_n = 2.0 * d - 1.0; + return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); +} + +vec4 filterColor(vec4 frag) { + const vec3 lum = vec3(0.21, 0.71, 0.07); + float grey = dot(frag.rgb, lum.rgb); + return vec4(grey, grey, grey, frag.a); +} + +vec3 getWorldPos(float depth) { + vec3 cameraPos = CameraDir * depth; + + vec3 worldPos = (uInverseView * vec4(cameraPos, 1)).xyz; + + return worldPos; +} + +float getDepth() { + float depth = texture2D(uDepth, Vertex.zw).r; + + depth = linearizeDepth(depth, uNearPlane, uFarPlane); + //depth = ( - uNearPlane) / (uFarPlane - uNearPlane); + depth = depth / uFarPlane; + + return depth; +} void main() { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + float depth = getDepth(); + vec3 worldPos = getWorldPos(depth); + + float distance = distance(uSphereCenter, worldPos); + float strength = smoothstep(uSphereRadius - uSphereFeather, uSphereRadius + uSphereFeather, distance); + + vec4 fragColor = texture2D(uColor, Vertex.zw); + + gl_FragColor = mix(fragColor, filterColor(fragColor), strength); + //gl_FragColor = vec4(worldPos, 1); } diff --git a/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert b/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert new file mode 100644 index 000000000..248157475 --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert @@ -0,0 +1,20 @@ +#version 120 + +attribute vec4 aVertex;// + +varying vec4 Vertex; +varying vec3 CameraDir; + +uniform mat4 uInverseProjection; + +void main() { + gl_Position = vec4(aVertex.xy, 0.0f, 1.0f); + Vertex = aVertex; + + vec4 clip = vec4(aVertex.xy, 0, 1); + + clip *= uInverseProjection; + + CameraDir = clip.xyz / clip.w; + //worldDirection = (uInverseProjection * vec4(aVertex.xy, 0, 1.)).xyz; +}