From 7988fb69a7c9ebaf19c333e6bf204c98640fd411 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 13 Apr 2021 23:52:52 -0700 Subject: [PATCH] Color matrices and many effect spheres --- .../foundation/mixin/RenderHooksMixin.java | 19 +- .../foundation/render/AllProgramSpecs.java | 12 +- .../render/backend/effects/ColorMatrices.java | 81 ++++++++ .../backend/effects/EffectsHandler.java | 43 ++++- .../effects/PostProcessingProgram.java | 76 -------- .../backend/effects/SphereFilterProgram.java | 177 ++++++++++++++++++ .../render/backend/gl/GlBuffer.java | 38 ++-- .../create/flywheel/shaders/area_effect.frag | 67 +++++++ .../create/flywheel/shaders/area_effect.vert | 22 +++ .../create/flywheel/shaders/chromatic.frag | 62 ------ .../create/flywheel/shaders/core/color.glsl | 22 +++ .../create/flywheel/shaders/screen_quad.vert | 20 -- 12 files changed, 449 insertions(+), 190 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java delete 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/SphereFilterProgram.java create mode 100644 src/main/resources/assets/create/flywheel/shaders/area_effect.frag create mode 100644 src/main/resources/assets/create/flywheel/shaders/area_effect.vert delete mode 100644 src/main/resources/assets/create/flywheel/shaders/chromatic.frag create mode 100644 src/main/resources/assets/create/flywheel/shaders/core/color.glsl delete mode 100644 src/main/resources/assets/create/flywheel/shaders/screen_quad.vert 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 2ea27cea7..d140a4bef 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java @@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.KineticRenderer; @@ -56,10 +57,6 @@ 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") @@ -72,14 +69,24 @@ public class RenderHooksMixin { double camZ = cameraPos.getZ(); CreateClient.kineticRenderer.get(world) - .beginFrame(info, camX, camY, camZ); + .beginFrame(info, camX, camY, camZ); ContraptionRenderDispatcher.beginFrame(info, camX, camY, camZ); } + @Inject(method = "render", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/shader/ShaderGroup;render(F)V")) + private void disableTransparencyShaderDepth(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) { + GlStateManager.depthMask(false); + } + + @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/renderer/ActiveRenderInfo;)V")) + private void applyFilters(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) { + Backend.effects.render(stack.peek().getModel()); + } + @Inject(at = @At("TAIL"), method = "scheduleBlockRerenderIfNeeded") private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) { CreateClient.kineticRenderer.get(world) - .update(world.getTileEntity(pos)); + .update(world.getTileEntity(pos)); } @Inject(at = @At("TAIL"), method = "loadRenderers") 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 8592dbeb4..df7bfb5b6 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java @@ -15,7 +15,7 @@ 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.effects.PostProcessingProgram; +import com.simibubi.create.foundation.render.backend.effects.SphereFilterProgram; 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; @@ -28,12 +28,12 @@ public class AllProgramSpecs { // noop, make sure the static field are loaded. } - public static final ProgramSpec CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(PostProcessingProgram::new)) + public static final ProgramSpec CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(SphereFilterProgram::new)) .addAttributes(ModelAttributes.class) .addAttributes(BasicAttributes.class) .addAttributes(TransformAttributes.class) - .setVert(Locations.SCREEN_QUAD) - .setFrag(Locations.CHROMATIC) + .setVert(Locations.EFFECT_VERT) + .setFrag(Locations.EFFECT_FRAG) .createProgramSpec()); public static final ProgramSpec MODEL = register(ProgramSpec.builder("model", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) @@ -131,8 +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 EFFECT_VERT = loc("area_effect.vert"); + public static final ResourceLocation EFFECT_FRAG = loc("area_effect.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/backend/effects/ColorMatrices.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java new file mode 100644 index 000000000..ab32b6b97 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java @@ -0,0 +1,81 @@ +package com.simibubi.create.foundation.render.backend.effects; + +import com.simibubi.create.foundation.utility.AngleHelper; + +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Matrix4f; + +public class ColorMatrices { + + public static final float lumaR = 0.3086f; + public static final float lumaG = 0.6094f; + public static final float lumaB = 0.0820f; + + public static Matrix4f grayscale() { + Matrix4f mat = new Matrix4f(); + + mat.a00 = mat.a01 = mat.a02 = lumaR; + mat.a10 = mat.a11 = mat.a12 = lumaG; + mat.a20 = mat.a21 = mat.a22 = lumaB; + mat.a33 = 1; + + return mat; + } + + public static Matrix4f saturate(float s) { + Matrix4f mat = new Matrix4f(); + + mat.a00 = (1.0f - s) * lumaR + s; + mat.a01 = (1.0f - s) * lumaR; + mat.a02 = (1.0f - s) * lumaR; + mat.a10 = (1.0f - s) * lumaG; + mat.a11 = (1.0f - s) * lumaG + s; + mat.a12 = (1.0f - s) * lumaG; + mat.a20 = (1.0f - s) * lumaB; + mat.a21 = (1.0f - s) * lumaB; + mat.a22 = (1.0f - s) * lumaB + s; + + mat.a33 = 1; + + return mat; + } + + public static Matrix4f sepia(float amount) { + Matrix4f mat = new Matrix4f(); + + mat.a00 = (float) (0.393 + 0.607 * (1 - amount)); + mat.a10 = (float) (0.769 - 0.769 * (1 - amount)); + mat.a20 = (float) (0.189 - 0.189 * (1 - amount)); + mat.a01 = (float) (0.349 - 0.349 * (1 - amount)); + mat.a11 = (float) (0.686 + 0.314 * (1 - amount)); + mat.a21 = (float) (0.168 - 0.168 * (1 - amount)); + mat.a02 = (float) (0.272 - 0.272 * (1 - amount)); + mat.a12 = (float) (0.534 - 0.534 * (1 - amount)); + mat.a22 = (float) (0.131 + 0.869 * (1 - amount)); + + mat.a33 = 1; + + return mat; + } + + // https://stackoverflow.com/a/8510751 + public static Matrix4f hueShift(float rot) { + Matrix4f mat = new Matrix4f(); + + mat.loadIdentity(); + + float cosA = MathHelper.cos(AngleHelper.rad(rot)); + float sinA = MathHelper.sin(AngleHelper.rad(rot)); + mat.a00 = (float) (cosA + (1.0 - cosA) / 3.0); + mat.a01 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA); + mat.a02 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA); + mat.a10 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA); + mat.a11 = (float) (cosA + 1. / 3. * (1.0 - cosA)); + mat.a12 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA); + mat.a20 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA); + mat.a21 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA); + mat.a22 = (float) (cosA + 1. / 3. * (1.0 - cosA)); + + return 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 e0bbdaadb..080825807 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 @@ -26,7 +26,7 @@ public class EffectsHandler { } public static float getFarPlane() { - return Minecraft.getInstance().gameRenderer.getFarPlaneDistance(); + return Minecraft.getInstance().gameRenderer.getFarPlaneDistance() * 4; } public static final float[] vertices = { @@ -75,6 +75,10 @@ public class EffectsHandler { } public void render(Matrix4f view) { +// if (true) { +// return; +// } + GL20.glEnable(GL20.GL_DEPTH_TEST); GL20.glDepthRange(getNearPlane(), getFarPlane()); @@ -87,8 +91,9 @@ public class EffectsHandler { Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer(); GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject); + GL30.glClear(GL30.GL_COLOR_BUFFER_BIT); - PostProcessingProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC); + SphereFilterProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC); program.bind(); program.bindColorTexture(mainBuffer.getColorAttachment()); @@ -104,15 +109,37 @@ public class EffectsHandler { Matrix4f inverseView = view.copy(); inverseView.invert(); -// Matrix4f inverseView = new Matrix4f(); -// inverseView.loadIdentity(); program.bindInverseView(inverseView); - Vector3d pos = new Vector3d(286, 73, -149); + Vector3d pos1 = new Vector3d(330, 0, 110); +// Vector3d pos1 = new Vector3d(852, 79, -204); +// Vector3d pos2 = new Vector3d(858, 95, -260); +// Vector3d pos3 = new Vector3d(906, 84, -207); Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView(); - Vector3d shaderPos = pos.subtract(cameraPos).scale(1 / getFarPlane()); - program.setSphere(shaderPos, 20f / getFarPlane(), 0.01f); + for (int i = 0; i < 16; i++) { + double angle = (Math.PI * AnimationTickHolder.getRenderTime() / 40) + i * Math.PI / 4; + + program.addSphere(new SphereFilterProgram.FilterSphere() + .setCenter(pos1.subtract(cameraPos).add(0, 0, i * 30)) + .setRadius(15) + .setFeather(0.5f) + .setFilter(ColorMatrices.hueShift((float) i / 16 * 360 + AnimationTickHolder.getRenderTime()))); + } + +// program.addSphere(new SphereFilterProgram.FilterSphere() +// .setCenter(pos2.subtract(cameraPos)) +// .setRadius(50) +// .setFeather(0.5f) +// .setFilter(ColorMatrices.sepia(1))); +// +// program.addSphere(new SphereFilterProgram.FilterSphere() +// .setCenter(pos3.subtract(cameraPos)) +// .setRadius(20) +// .setFeather(3f) +// .setFilter(ColorMatrices.saturate(4))); + + program.uploadFilters(); program.setFarPlane(getFarPlane()); program.setNearPlane(getNearPlane()); @@ -123,7 +150,9 @@ public class EffectsHandler { program.bindColorTexture(0); program.bindDepthTexture(0); + GL20.glActiveTexture(GL20.GL_TEXTURE0); + program.clear(); program.unbind(); GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject); 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 deleted file mode 100644 index 19f239ad2..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/PostProcessingProgram.java +++ /dev/null @@ -1,76 +0,0 @@ -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/SphereFilterProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java new file mode 100644 index 000000000..ab25bb6bf --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java @@ -0,0 +1,177 @@ +package com.simibubi.create.foundation.render.backend.effects; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.ArrayList; + +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL31; + +import com.simibubi.create.foundation.render.backend.RenderUtil; +import com.simibubi.create.foundation.render.backend.gl.GlBuffer; +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 SphereFilterProgram extends GlProgram { + + protected static final int BLOCK_BINDING = 4; + + protected static final int SPHERE_FILTER_SIZE = 4 * 16 + 16 + 4 * 16 * 16; + + protected static final int MAX_FILTERS = 16; + + protected static final int BUFFER_SIZE = 4 + MAX_FILTERS * SPHERE_FILTER_SIZE; + + GlBuffer effectsUBO; + + protected final ArrayList filters = new ArrayList<>(16); + + protected final int uniformBlock; + + protected final int uDepth; + protected final int uColor; + + protected final int uInverseProjection; + protected final int uInverseView; + + protected final int uNearPlane; + protected final int uFarPlane; +// protected final int uSphereCenter; +// protected final int uSphereRadius; +// protected final int uSphereFeather; +// protected final int uColorFilter; + + public SphereFilterProgram(ResourceLocation name, int handle) { + super(name, handle); + + effectsUBO = new GlBuffer(GL31.GL_UNIFORM_BUFFER); + + uniformBlock = GL31.glGetUniformBlockIndex(handle, "Filters"); + + GL31.glUniformBlockBinding(handle, uniformBlock, BLOCK_BINDING); + + effectsUBO.bind(); + effectsUBO.alloc(BUFFER_SIZE, GL20.GL_STATIC_DRAW); + GL31.glBindBufferBase(effectsUBO.getBufferType(), BLOCK_BINDING, effectsUBO.handle()); + effectsUBO.unbind(); + + uInverseProjection = getUniformLocation("uInverseProjection"); + uInverseView = getUniformLocation("uInverseView"); + uNearPlane = getUniformLocation("uNearPlane"); + uFarPlane = getUniformLocation("uFarPlane"); +// +// uSphereCenter = getUniformLocation("uSphereCenter"); +// uSphereRadius = getUniformLocation("uSphereRadius"); +// uSphereFeather = getUniformLocation("uSphereFeather"); +// uColorFilter = getUniformLocation("uColorFilter"); + + 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 clear() { + filters.clear(); + } + + public void addSphere(FilterSphere filterSphere) { + filters.add(filterSphere); + } + + public void uploadFilters() { + effectsUBO.bind(GL20.GL_ARRAY_BUFFER); + effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, this::uploadUBO); + effectsUBO.unbind(GL20.GL_ARRAY_BUFFER); + } + +// public void setSphere(FilterSphere sphere) { +// GL20.glUniform3f(uSphereCenter, (float) sphere.center.x, (float) sphere.center.y, (float) sphere.center.z); +// +// GL20.glUniform1f(uSphereRadius, sphere.radius); +// GL20.glUniform1f(uSphereFeather, sphere.feather); +// +// uploadMatrixUniform(uColorFilter, sphere.filter); +// } + + 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); + } + + private void uploadUBO(ByteBuffer buf) { + buf.putInt(filters.size()); + buf.position(16); + FloatBuffer floatBuffer = buf.asFloatBuffer(); + + //floatBuffer.position(4); + filters.forEach(it -> it.write(floatBuffer)); + } + + public static class FilterSphere { + public Vector3d center; + public float radius; + public float feather; + + public Matrix4f filter; + + public FilterSphere setCenter(Vector3d center) { + this.center = center; + return this; + } + + public FilterSphere setRadius(float radius) { + this.radius = radius; + return this; + } + + public FilterSphere setFeather(float feather) { + this.feather = feather; + return this; + } + + public FilterSphere setFilter(Matrix4f filter) { + this.filter = filter; + return this; + } + + public void write(FloatBuffer buf) { + buf.put(new float[]{ + (float) center.x, + (float) center.y, + (float) center.z, + radius, + feather, + 0, + 0, + 0 + }); + + buf.put(RenderUtil.writeMatrix(filter)); + } + } +} 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 7cb688703..7680f1790 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 @@ -12,20 +12,28 @@ public class GlBuffer extends GlObject { protected final int bufferType; - public GlBuffer(int bufferType) { - setHandle(GL20.glGenBuffers()); - this.bufferType = bufferType; - } + public GlBuffer(int bufferType) { + setHandle(GL20.glGenBuffers()); + this.bufferType = bufferType; + } - public int getBufferType() { - return bufferType; + public int getBufferType() { + return bufferType; } public void bind() { - GL20.glBindBuffer(bufferType, handle()); + bind(bufferType); + } + + public void bind(int type) { + GL20.glBindBuffer(type, handle()); } public void unbind() { + unbind(bufferType); + } + + public void unbind(int bufferType) { GL20.glBindBuffer(bufferType, 0); } @@ -43,11 +51,15 @@ public class GlBuffer extends GlObject { Backend.compat.mapBuffer(bufferType, 0, length, upload); } - public void map(int offset, int length, Consumer upload) { - Backend.compat.mapBuffer(bufferType, offset, length, upload); - } + public void map(int offset, int length, Consumer upload) { + Backend.compat.mapBuffer(bufferType, offset, length, upload); + } - protected void deleteInternal(int handle) { - GL20.glDeleteBuffers(handle); - } + public void map(int type, int offset, int length, Consumer upload) { + Backend.compat.mapBuffer(type, offset, length, upload); + } + + protected void deleteInternal(int handle) { + GL20.glDeleteBuffers(handle); + } } diff --git a/src/main/resources/assets/create/flywheel/shaders/area_effect.frag b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag new file mode 100644 index 000000000..0d2b4659a --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag @@ -0,0 +1,67 @@ +#version 140 + +#flwinclude <"create:core/color.glsl"> + +in vec2 ScreenCoord; +in vec3 WorldDir; + +out vec4 Color; + +// constants +uniform sampler2D uDepth; +uniform sampler2D uColor; +uniform float uNearPlane = 0.15; +uniform float uFarPlane = 1.; + +struct SphereFilter { + vec4 sphere;// + float feather; + mat4 colorOp; +}; + +#define N 16 +layout (std140) uniform Filters { + int uCount; + SphereFilter uSpheres[N]; +}; + +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(mat4 colorOp, vec4 frag) { + // preserve alpha while transforming color + vec4 i = vec4(frag.rgb, 1.); + i *= colorOp; + return vec4(i.rgb, frag.a); +} + +float getDepth() { + float depth = texture2D(uDepth, ScreenCoord).r; + + depth = linearizeDepth(depth, uNearPlane, uFarPlane); + //depth = ( - uNearPlane) / (uFarPlane - uNearPlane); + //depth = depth / uFarPlane; + + return depth; +} + +void main() { + float depth = getDepth(); + vec3 worldPos = WorldDir * depth; + + vec4 accum = texture2D(uColor, ScreenCoord); + + for (int i = 0; i < uCount; i++) { + SphereFilter s = uSpheres[i]; + + float distance = distance(s.sphere.xyz, worldPos); + float strength = 1 - smoothstep(s.sphere.w - s.feather, s.sphere.w + s.feather, distance); + + accum = mix(accum, filterColor(s.colorOp, accum), strength); + } + + Color = accum; + //Color = vec4(vec3(distance / uFarPlane), 1.); +} diff --git a/src/main/resources/assets/create/flywheel/shaders/area_effect.vert b/src/main/resources/assets/create/flywheel/shaders/area_effect.vert new file mode 100644 index 000000000..525191aa1 --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/area_effect.vert @@ -0,0 +1,22 @@ +#version 140 + +in vec4 aVertex;// + +out vec2 ScreenCoord; +out vec3 WorldDir; + +uniform mat4 uInverseProjection; +uniform mat4 uInverseView; + +void main() { + gl_Position = vec4(aVertex.xy, 0., 1.); + ScreenCoord = aVertex.zw; + + vec4 clip = vec4(aVertex.xy, 0., 1.); + + clip *= uInverseProjection; + + vec3 cameraDir = clip.xyz / clip.w; + WorldDir = (uInverseView * vec4(cameraDir, 1.)).xyz; + //worldDirection = (uInverseProjection * vec4(aVertex.xy, 0, 1.)).xyz; +} diff --git a/src/main/resources/assets/create/flywheel/shaders/chromatic.frag b/src/main/resources/assets/create/flywheel/shaders/chromatic.frag deleted file mode 100644 index bd70e8d22..000000000 --- a/src/main/resources/assets/create/flywheel/shaders/chromatic.frag +++ /dev/null @@ -1,62 +0,0 @@ -#version 120 - -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() { - 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/core/color.glsl b/src/main/resources/assets/create/flywheel/shaders/core/color.glsl new file mode 100644 index 000000000..f6f9d271b --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/core/color.glsl @@ -0,0 +1,22 @@ +// All components are in the range [0…1], including hue. +vec3 rgb2hsv(vec3 c) { + const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +// All components are in the range [0…1], including hue. +vec3 hsv2rgb(vec3 hsv) { + const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(hsv.xxx + K.xyz) * 6.0 - K.www); + return hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y); +} + +vec3 hsv2rgbWrapped(vec3 hsv) { + hsv.x = fract(hsv.x); + return hsv2rgb(hsv); +} diff --git a/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert b/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert deleted file mode 100644 index 248157475..000000000 --- a/src/main/resources/assets/create/flywheel/shaders/screen_quad.vert +++ /dev/null @@ -1,20 +0,0 @@ -#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; -}