From a3d0b0241d43f70e722b91d612e5cb921cb1e152 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Wed, 29 Oct 2025 01:52:36 -0400 Subject: [PATCH 1/4] implement fixed sized ubo storage --- .../renderer/FixedUniformStorage.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/renderer/FixedUniformStorage.java diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/FixedUniformStorage.java b/src/main/java/meteordevelopment/meteorclient/renderer/FixedUniformStorage.java new file mode 100644 index 0000000000..11dc24c1cb --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/renderer/FixedUniformStorage.java @@ -0,0 +1,93 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.renderer; + +import com.mojang.blaze3d.buffers.GpuBuffer; +import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.systems.GpuDevice; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gl.DynamicUniformStorage; +import net.minecraft.client.gl.MappableRingBuffer; +import net.minecraft.util.math.MathHelper; + +import java.nio.ByteBuffer; + +/** + * UBO storage with a constant size. Exceeding this size causes an {@link IndexOutOfBoundsException} to be thrown. + * + * @see DynamicUniformStorage + * @author Crosby + */ +public class FixedUniformStorage { + private final MappableRingBuffer buffer; + private final int blockSize; + private final int capacity; + private int size; + + public FixedUniformStorage(String name, int blockSize, int capacity) { + GpuDevice gpuDevice = RenderSystem.getDevice(); + this.blockSize = MathHelper.roundUpToMultiple(blockSize, gpuDevice.getUniformOffsetAlignment()); + this.capacity = capacity; + int alignedCapacity = MathHelper.smallestEncompassingPowerOfTwo(capacity); + this.size = 0; + this.buffer = new MappableRingBuffer(() -> name + " x" + this.blockSize, 130, this.blockSize * alignedCapacity); + } + + public GpuBufferSlice write(T value) { + if (this.size >= this.capacity) { + throw new IndexOutOfBoundsException(String.format("Index %s out of bounds for length %s", this.size, this.capacity)); + } else { + int i = this.size * this.blockSize; + GpuBufferSlice slice = this.buffer.getBlocking().slice(i, this.blockSize); + + try (GpuBuffer.MappedView mappedView = RenderSystem.getDevice() + .createCommandEncoder() + .mapBuffer(slice, false, true)) { + value.write(mappedView.data()); + } + + this.size++; + return slice; + } + } + + public GpuBufferSlice[] writeAll(T[] values) { + if (values.length == 0) { + return new GpuBufferSlice[0]; + } else if (this.size + values.length > this.capacity) { + throw new IndexOutOfBoundsException(String.format("Index %s out of bounds for length %s", this.size + values.length - 1, this.capacity)); + } else { + int i = this.size * this.blockSize; + GpuBufferSlice[] gpuBufferSlices = new GpuBufferSlice[values.length]; + GpuBuffer ubo = this.buffer.getBlocking(); + + try (GpuBuffer.MappedView mappedView = RenderSystem.getDevice() + .createCommandEncoder() + .mapBuffer(ubo.slice(i, values.length * this.blockSize), false, true)) { + ByteBuffer byteBuffer = mappedView.data(); + + for (int j = 0; j < values.length; j++) { + T uploadable = values[j]; + gpuBufferSlices[j] = ubo.slice(i + j * this.blockSize, this.blockSize); + byteBuffer.position(j * this.blockSize); + uploadable.write(byteBuffer); + } + } + + this.size += values.length; + return gpuBufferSlices; + } + } + + public void clear() { + this.size = 0; + this.buffer.rotate(); + } + + public void close() { + this.buffer.close(); + } +} From 55d9ff011ca686d4c41529b1096bbc298380a2c9 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Wed, 29 Oct 2025 01:54:41 -0400 Subject: [PATCH 2/4] make `MeshRenderer` support vbo/ibo --- .../meteorclient/renderer/MeshRenderer.java | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java b/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java index 4bc59cca85..3196351007 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java @@ -19,6 +19,7 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.ColorHelper; import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import java.util.HashMap; @@ -36,7 +37,9 @@ public class MeshRenderer { private GpuTextureView depthAttachment; private Color clearColor; private RenderPipeline pipeline; - private MeshBuilder mesh; + private @Nullable MeshBuilder mesh; + private @Nullable GpuBuffer vertexBuffer; + private @Nullable GpuBuffer indexBuffer; private Matrix4f matrix; private final HashMap uniforms = new HashMap<>(); private final HashMap samplers = new HashMap<>(); @@ -73,6 +76,12 @@ public MeshRenderer pipeline(RenderPipeline pipeline) { return this; } + public MeshRenderer mesh(GpuBuffer vertices, GpuBuffer indices) { + this.vertexBuffer = vertices; + this.indexBuffer = indices; + return this; + } + public MeshRenderer mesh(MeshBuilder mesh) { this.mesh = mesh; return this; @@ -80,12 +89,20 @@ public MeshRenderer mesh(MeshBuilder mesh) { public MeshRenderer mesh(MeshBuilder mesh, Matrix4f matrix) { this.mesh = mesh; - this.matrix = matrix; - return this; + return this.transform(matrix); } public MeshRenderer mesh(MeshBuilder mesh, MatrixStack matrices) { this.mesh = mesh; + return this.transform(matrices); + } + + public MeshRenderer transform(Matrix4f matrix) { + this.matrix = matrix; + return this; + } + + public MeshRenderer transform(MatrixStack matrices) { this.matrix = matrices.peek().getPositionMatrix(); return this; } @@ -104,11 +121,15 @@ public MeshRenderer sampler(String name, GpuTextureView view) { } public void end() { - if (mesh.isBuilding()) { + if (mesh != null && mesh.isBuilding()) { mesh.end(); } - if (mesh.getIndicesCount() > 0) { + int indexCount = mesh != null ? mesh.getIndicesCount() + : (indexBuffer != null ? indexBuffer.size() / Integer.BYTES : -1); + + if (indexCount > 0) { + if (Utils.rendering3D || matrix != null) { RenderSystem.getModelViewStack().pushMatrix(); } @@ -121,8 +142,8 @@ public void end() { applyCameraPos(); } - GpuBuffer vertexBuffer = mesh.getVertexBuffer(); - GpuBuffer indexBuffer = mesh.getIndexBuffer(); + GpuBuffer vertexBuffer = mesh != null ? mesh.getVertexBuffer() : this.vertexBuffer; + GpuBuffer indexBuffer = mesh != null ? mesh.getIndexBuffer() : this.indexBuffer; { OptionalInt clearColor = this.clearColor != null ? @@ -148,7 +169,7 @@ public void end() { pass.setVertexBuffer(0, vertexBuffer); pass.setIndexBuffer(indexBuffer, VertexFormat.IndexType.INT); - pass.drawIndexed(0, 0, mesh.getIndicesCount(), 1); + pass.drawIndexed(0, 0, indexCount, 1); pass.close(); } @@ -163,6 +184,8 @@ public void end() { clearColor = null; pipeline = null; mesh = null; + vertexBuffer = null; + indexBuffer = null; matrix = null; uniforms.clear(); samplers.clear(); From f95995bd4c72665a193c65e869d569b430754583 Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Wed, 29 Oct 2025 01:55:26 -0400 Subject: [PATCH 3/4] deprecate `FullScreenRenderer#mesh` --- .../meteorclient/renderer/FullScreenRenderer.java | 13 ++++++++++++- .../meteorclient/renderer/MeshRenderer.java | 4 ++++ .../meteorclient/systems/modules/render/Blur.java | 6 +++--- .../utils/render/postprocess/PostProcessShader.java | 3 +-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/FullScreenRenderer.java b/src/main/java/meteordevelopment/meteorclient/renderer/FullScreenRenderer.java index 13826371d4..0657b05fc1 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/FullScreenRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/FullScreenRenderer.java @@ -5,10 +5,19 @@ package meteordevelopment.meteorclient.renderer; +import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.vertex.VertexFormat; import meteordevelopment.meteorclient.utils.PreInit; public class FullScreenRenderer { + public static GpuBuffer vbo; + public static GpuBuffer ibo; + + /** + * Deprecated for performance reasons, use {@link MeshRenderer#fullscreen()} or the {@link FullScreenRenderer#vbo} + * and {@link FullScreenRenderer#ibo} buffer objects instead. + */ + @Deprecated(forRemoval = true) public static MeshBuilder mesh; private FullScreenRenderer() {} @@ -18,7 +27,6 @@ public static void init() { mesh = new MeshBuilder(MeteorVertexFormats.POS2, VertexFormat.DrawMode.TRIANGLES, 4, 6); mesh.begin(); - mesh.ensureQuadCapacity(); mesh.quad( mesh.vec2(-1, -1).next(), @@ -28,5 +36,8 @@ public static void init() { ); mesh.end(); + + vbo = mesh.getVertexBuffer(); + ibo = mesh.getIndexBuffer(); } } diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java b/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java index 3196351007..0e098290cb 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/MeshRenderer.java @@ -107,6 +107,10 @@ public MeshRenderer transform(MatrixStack matrices) { return this; } + public MeshRenderer fullscreen() { + return this.mesh(FullScreenRenderer.vbo, FullScreenRenderer.ibo); + } + public MeshRenderer uniform(String name, GpuBufferSlice slice) { uniforms.put(name, slice); return this; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java index aad6eb3485..65d1e728ec 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java @@ -18,7 +18,7 @@ import meteordevelopment.meteorclient.events.render.RenderAfterWorldEvent; import meteordevelopment.meteorclient.gui.WidgetScreen; import meteordevelopment.meteorclient.mixininterface.IGpuTexture; -import meteordevelopment.meteorclient.renderer.FullScreenRenderer; +import meteordevelopment.meteorclient.renderer.FixedUniformStorage; import meteordevelopment.meteorclient.renderer.MeshRenderer; import meteordevelopment.meteorclient.renderer.MeteorRenderPipelines; import meteordevelopment.meteorclient.settings.BoolSetting; @@ -211,7 +211,7 @@ private void onRenderAfterWorld() { MeshRenderer.begin() .attachments(mc.getFramebuffer()) .pipeline(MeteorRenderPipelines.BLUR_PASSTHROUGH) - .mesh(FullScreenRenderer.mesh) + .fullscreen() .sampler("u_Texture", fbos[0]) .end(); } @@ -225,11 +225,11 @@ private void renderToFbo(GpuTextureView targetFbo, GpuTextureView sourceTexture, MeshRenderer.begin() .attachments(targetFbo, null) .pipeline(pipeline) - .mesh(FullScreenRenderer.mesh) .uniform("BlurData", UNIFORM_STORAGE.write(new UniformData( 0.5f / targetFbo.getWidth(0), 0.5f / targetFbo.getHeight(0), (float) offset ))) + .fullscreen() .sampler("u_Texture", sourceTexture) .end(); diff --git a/src/main/java/meteordevelopment/meteorclient/utils/render/postprocess/PostProcessShader.java b/src/main/java/meteordevelopment/meteorclient/utils/render/postprocess/PostProcessShader.java index 5a599c088e..025feb5cc5 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/render/postprocess/PostProcessShader.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/render/postprocess/PostProcessShader.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.buffers.Std140SizeCalculator; import com.mojang.blaze3d.pipeline.RenderPipeline; import meteordevelopment.meteorclient.MeteorClient; -import meteordevelopment.meteorclient.renderer.FullScreenRenderer; import meteordevelopment.meteorclient.renderer.MeshRenderer; import meteordevelopment.meteorclient.utils.render.CustomOutlineVertexConsumerProvider; import net.minecraft.client.gl.DynamicUniformStorage; @@ -51,7 +50,7 @@ public void endRender(Runnable draw) { var renderer = MeshRenderer.begin() .attachments(mc.getFramebuffer()) .pipeline(pipeline) - .mesh(FullScreenRenderer.mesh) + .fullscreen() .uniform("PostData", UNIFORM_STORAGE.write(new UniformData( (float) mc.getWindow().getFramebufferWidth(), (float) mc.getWindow().getFramebufferHeight(), (float) glfwGetTime() From 4f57543db5106c271996d3ab66e29be3695e439f Mon Sep 17 00:00:00 2001 From: RacoonDog <32882447+racoondog@users.noreply.github.com> Date: Wed, 29 Oct 2025 01:55:48 -0400 Subject: [PATCH 4/4] blur optimizations --- .../meteorclient/mixin/RenderSystemMixin.java | 2 - .../systems/modules/render/Blur.java | 113 ++++++++++-------- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/RenderSystemMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/RenderSystemMixin.java index 45a95f68b1..164b7b7105 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/RenderSystemMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/RenderSystemMixin.java @@ -7,7 +7,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import meteordevelopment.meteorclient.renderer.MeshUniforms; -import meteordevelopment.meteorclient.systems.modules.render.Blur; import meteordevelopment.meteorclient.utils.render.postprocess.ChamsShader; import meteordevelopment.meteorclient.utils.render.postprocess.OutlineUniforms; import meteordevelopment.meteorclient.utils.render.postprocess.PostProcessShader; @@ -21,7 +20,6 @@ public abstract class RenderSystemMixin { @Inject(method = "flipFrame", at = @At("TAIL")) private static void meteor$flipFrame(CallbackInfo info) { MeshUniforms.flipFrame(); - Blur.flipFrame(); PostProcessShader.flipFrame(); ChamsShader.flipFrame(); OutlineUniforms.flipFrame(); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java index 65d1e728ec..6162fb333e 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Blur.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.systems.modules.render; +import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.buffers.Std140Builder; import com.mojang.blaze3d.buffers.Std140SizeCalculator; import com.mojang.blaze3d.pipeline.RenderPipeline; @@ -12,7 +13,7 @@ import com.mojang.blaze3d.textures.AddressMode; import com.mojang.blaze3d.textures.GpuTextureView; import com.mojang.blaze3d.textures.TextureFormat; -import it.unimi.dsi.fastutil.ints.IntDoubleImmutablePair; +import it.unimi.dsi.fastutil.ints.IntFloatImmutablePair; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.events.game.ResolutionChangedEvent; import meteordevelopment.meteorclient.events.render.RenderAfterWorldEvent; @@ -40,27 +41,27 @@ public class Blur extends Module { private final SettingGroup sgScreens = settings.createGroup("Screens"); // Strength-Levels from https://github.com/jonaburg/picom/blob/a8445684fe18946604848efb73ace9457b29bf80/src/backend/backend_common.c#L372 - private final IntDoubleImmutablePair[] strengths = new IntDoubleImmutablePair[]{ - IntDoubleImmutablePair.of(1, 1.25), // LVL 1 - IntDoubleImmutablePair.of(1, 2.25), // LVL 2 - IntDoubleImmutablePair.of(2, 2.0), // LVL 3 - IntDoubleImmutablePair.of(2, 3.0), // LVL 4 - IntDoubleImmutablePair.of(2, 4.25), // LVL 5 - IntDoubleImmutablePair.of(3, 2.5), // LVL 6 - IntDoubleImmutablePair.of(3, 3.25), // LVL 7 - IntDoubleImmutablePair.of(3, 4.25), // LVL 8 - IntDoubleImmutablePair.of(3, 5.5), // LVL 9 - IntDoubleImmutablePair.of(4, 3.25), // LVL 10 - IntDoubleImmutablePair.of(4, 4.0), // LVL 11 - IntDoubleImmutablePair.of(4, 5.0), // LVL 12 - IntDoubleImmutablePair.of(4, 6.0), // LVL 13 - IntDoubleImmutablePair.of(4, 7.25), // LVL 14 - IntDoubleImmutablePair.of(4, 8.25), // LVL 15 - IntDoubleImmutablePair.of(5, 4.5), // LVL 16 - IntDoubleImmutablePair.of(5, 5.25), // LVL 17 - IntDoubleImmutablePair.of(5, 6.25), // LVL 18 - IntDoubleImmutablePair.of(5, 7.25), // LVL 19 - IntDoubleImmutablePair.of(5, 8.5) // LVL 20 + private final IntFloatImmutablePair[] strengths = new IntFloatImmutablePair[]{ + IntFloatImmutablePair.of(1, 1.25f), // LVL 1 + IntFloatImmutablePair.of(1, 2.25f), // LVL 2 + IntFloatImmutablePair.of(2, 2.0f), // LVL 3 + IntFloatImmutablePair.of(2, 3.0f), // LVL 4 + IntFloatImmutablePair.of(2, 4.25f), // LVL 5 + IntFloatImmutablePair.of(3, 2.5f), // LVL 6 + IntFloatImmutablePair.of(3, 3.25f), // LVL 7 + IntFloatImmutablePair.of(3, 4.25f), // LVL 8 + IntFloatImmutablePair.of(3, 5.5f), // LVL 9 + IntFloatImmutablePair.of(4, 3.25f), // LVL 10 + IntFloatImmutablePair.of(4, 4.0f), // LVL 11 + IntFloatImmutablePair.of(4, 5.0f), // LVL 12 + IntFloatImmutablePair.of(4, 6.0f), // LVL 13 + IntFloatImmutablePair.of(4, 7.25f), // LVL 14 + IntFloatImmutablePair.of(4, 8.25f), // LVL 15 + IntFloatImmutablePair.of(5, 4.5f), // LVL 16 + IntFloatImmutablePair.of(5, 5.25f), // LVL 17 + IntFloatImmutablePair.of(5, 6.25f), // LVL 18 + IntFloatImmutablePair.of(5, 7.25f), // LVL 19 + IntFloatImmutablePair.of(5, 8.5f) // LVL 20 }; // General @@ -113,14 +114,20 @@ public class Blur extends Module { ); private final GpuTextureView[] fbos = new GpuTextureView[6]; - private boolean initialized; + private GpuBufferSlice[] ubos; private boolean enabled; private long fadeEndAt; + private float previousOffset = -1; public Blur() { super(Categories.Render, "blur", "Blurs background when in GUI screens."); + // Initialize fbos for the first time + for (int i = 0; i < fbos.length; i++) { + fbos[i] = createFbo(i); + } + // The listeners need to run even when the module is not enabled MeteorClient.EVENT_BUS.subscribe(new ConsumerListener<>(ResolutionChangedEvent.class, event -> { // Resize all fbos @@ -131,6 +138,9 @@ public Blur() { fbos[i] = createFbo(i); } + + // Invalidate ubos + previousOffset = -1; })); MeteorClient.EVENT_BUS.subscribe(new ConsumerListener<>(RenderAfterWorldEvent.class, event -> onRenderAfterWorld())); @@ -168,17 +178,6 @@ private void onRenderAfterWorld() { if (!enabled) return; - // Initialize shader and framebuffer if running for the first time - if (!initialized) { - for (int i = 0; i < fbos.length; i++) { - if (fbos[i] == null) { - fbos[i] = createFbo(i); - } - } - - initialized = true; - } - // Update progress double progress = 1; @@ -190,21 +189,27 @@ private void onRenderAfterWorld() { } // Update strength - IntDoubleImmutablePair strength = strengths[(int) ((this.strength.get() - 1) * progress)]; + IntFloatImmutablePair strength = strengths[(int) ((this.strength.get() - 1) * progress)]; int iterations = strength.leftInt(); - double offset = strength.rightDouble(); + float offset = strength.rightFloat(); + + // Update uniforms + if (previousOffset != offset) { + updateUniforms(offset); + previousOffset = offset; + } // Initial downsample - renderToFbo(fbos[0], mc.getFramebuffer().getColorAttachmentView(), MeteorRenderPipelines.BLUR_DOWN, offset); + renderToFbo(fbos[0], mc.getFramebuffer().getColorAttachmentView(), MeteorRenderPipelines.BLUR_DOWN, ubos[0]); // Downsample for (int i = 0; i < iterations; i++) { - renderToFbo(fbos[i + 1], fbos[i], MeteorRenderPipelines.BLUR_DOWN, offset); + renderToFbo(fbos[i + 1], fbos[i], MeteorRenderPipelines.BLUR_DOWN, ubos[i + 1]); } // Upsample for (int i = iterations; i >= 1; i--) { - renderToFbo(fbos[i - 1], fbos[i], MeteorRenderPipelines.BLUR_UP, offset); + renderToFbo(fbos[i - 1], fbos[i], MeteorRenderPipelines.BLUR_UP, ubos[i - 1]); } // Render output @@ -216,7 +221,7 @@ private void onRenderAfterWorld() { .end(); } - private void renderToFbo(GpuTextureView targetFbo, GpuTextureView sourceTexture, RenderPipeline pipeline, double offset) { + private void renderToFbo(GpuTextureView targetFbo, GpuTextureView sourceTexture, RenderPipeline pipeline, GpuBufferSlice ubo) { AddressMode prevAddressModeU = ((IGpuTexture) sourceTexture.texture()).meteor$getAddressModeU(); AddressMode prevAddressModeV = ((IGpuTexture) sourceTexture.texture()).meteor$getAddressModeV(); @@ -225,11 +230,8 @@ private void renderToFbo(GpuTextureView targetFbo, GpuTextureView sourceTexture, MeshRenderer.begin() .attachments(targetFbo, null) .pipeline(pipeline) - .uniform("BlurData", UNIFORM_STORAGE.write(new UniformData( - 0.5f / targetFbo.getWidth(0), 0.5f / targetFbo.getHeight(0), - (float) offset - ))) .fullscreen() + .uniform("BlurData", ubo) .sampler("u_Texture", sourceTexture) .end(); @@ -250,18 +252,29 @@ private boolean shouldRender() { // Uniforms + private void updateUniforms(float offset) { + UNIFORM_STORAGE.clear(); + + BlurUniformData[] uboData = new BlurUniformData[6]; + for (int i = 0; i < uboData.length; i++) { + GpuTextureView fbo = fbos[i]; + uboData[i] = new BlurUniformData( + 0.5f / fbo.getWidth(0), 0.5f / fbo.getHeight(0), + offset + ); + } + + ubos = UNIFORM_STORAGE.writeAll(uboData); + } + private static final int UNIFORM_SIZE = new Std140SizeCalculator() .putVec2() .putFloat() .get(); - private static final DynamicUniformStorage UNIFORM_STORAGE = new DynamicUniformStorage<>("Meteor - Blur UBO", UNIFORM_SIZE, 16); - - public static void flipFrame() { - UNIFORM_STORAGE.clear(); - } + private static final FixedUniformStorage UNIFORM_STORAGE = new FixedUniformStorage<>("Meteor - Blur UBO", UNIFORM_SIZE, 6); - private record UniformData(float halfTexelSizeX, float halfTexelSizeY, float offset) implements DynamicUniformStorage.Uploadable { + private record BlurUniformData(float halfTexelSizeX, float halfTexelSizeY, float offset) implements DynamicUniformStorage.Uploadable { @Override public void write(ByteBuffer buffer) { Std140Builder.intoBuffer(buffer)