55
66package meteordevelopment .meteorclient .systems .modules .render ;
77
8+ import com .mojang .blaze3d .buffers .GpuBufferSlice ;
89import com .mojang .blaze3d .buffers .Std140Builder ;
910import com .mojang .blaze3d .buffers .Std140SizeCalculator ;
1011import com .mojang .blaze3d .pipeline .RenderPipeline ;
1112import com .mojang .blaze3d .systems .RenderSystem ;
1213import com .mojang .blaze3d .textures .AddressMode ;
1314import com .mojang .blaze3d .textures .GpuTextureView ;
1415import com .mojang .blaze3d .textures .TextureFormat ;
15- import it .unimi .dsi .fastutil .ints .IntDoubleImmutablePair ;
16+ import it .unimi .dsi .fastutil .ints .IntFloatImmutablePair ;
1617import meteordevelopment .meteorclient .MeteorClient ;
1718import meteordevelopment .meteorclient .events .game .ResolutionChangedEvent ;
1819import meteordevelopment .meteorclient .events .render .RenderAfterWorldEvent ;
@@ -40,27 +41,27 @@ public class Blur extends Module {
4041 private final SettingGroup sgScreens = settings .createGroup ("Screens" );
4142
4243 // Strength-Levels from https://github.com/jonaburg/picom/blob/a8445684fe18946604848efb73ace9457b29bf80/src/backend/backend_common.c#L372
43- private final IntDoubleImmutablePair [] strengths = new IntDoubleImmutablePair []{
44- IntDoubleImmutablePair .of (1 , 1.25 ), // LVL 1
45- IntDoubleImmutablePair .of (1 , 2.25 ), // LVL 2
46- IntDoubleImmutablePair .of (2 , 2.0 ), // LVL 3
47- IntDoubleImmutablePair .of (2 , 3.0 ), // LVL 4
48- IntDoubleImmutablePair .of (2 , 4.25 ), // LVL 5
49- IntDoubleImmutablePair .of (3 , 2.5 ), // LVL 6
50- IntDoubleImmutablePair .of (3 , 3.25 ), // LVL 7
51- IntDoubleImmutablePair .of (3 , 4.25 ), // LVL 8
52- IntDoubleImmutablePair .of (3 , 5.5 ), // LVL 9
53- IntDoubleImmutablePair .of (4 , 3.25 ), // LVL 10
54- IntDoubleImmutablePair .of (4 , 4.0 ), // LVL 11
55- IntDoubleImmutablePair .of (4 , 5.0 ), // LVL 12
56- IntDoubleImmutablePair .of (4 , 6.0 ), // LVL 13
57- IntDoubleImmutablePair .of (4 , 7.25 ), // LVL 14
58- IntDoubleImmutablePair .of (4 , 8.25 ), // LVL 15
59- IntDoubleImmutablePair .of (5 , 4.5 ), // LVL 16
60- IntDoubleImmutablePair .of (5 , 5.25 ), // LVL 17
61- IntDoubleImmutablePair .of (5 , 6.25 ), // LVL 18
62- IntDoubleImmutablePair .of (5 , 7.25 ), // LVL 19
63- IntDoubleImmutablePair .of (5 , 8.5 ) // LVL 20
44+ private final IntFloatImmutablePair [] strengths = new IntFloatImmutablePair []{
45+ IntFloatImmutablePair .of (1 , 1.25f ), // LVL 1
46+ IntFloatImmutablePair .of (1 , 2.25f ), // LVL 2
47+ IntFloatImmutablePair .of (2 , 2.0f ), // LVL 3
48+ IntFloatImmutablePair .of (2 , 3.0f ), // LVL 4
49+ IntFloatImmutablePair .of (2 , 4.25f ), // LVL 5
50+ IntFloatImmutablePair .of (3 , 2.5f ), // LVL 6
51+ IntFloatImmutablePair .of (3 , 3.25f ), // LVL 7
52+ IntFloatImmutablePair .of (3 , 4.25f ), // LVL 8
53+ IntFloatImmutablePair .of (3 , 5.5f ), // LVL 9
54+ IntFloatImmutablePair .of (4 , 3.25f ), // LVL 10
55+ IntFloatImmutablePair .of (4 , 4.0f ), // LVL 11
56+ IntFloatImmutablePair .of (4 , 5.0f ), // LVL 12
57+ IntFloatImmutablePair .of (4 , 6.0f ), // LVL 13
58+ IntFloatImmutablePair .of (4 , 7.25f ), // LVL 14
59+ IntFloatImmutablePair .of (4 , 8.25f ), // LVL 15
60+ IntFloatImmutablePair .of (5 , 4.5f ), // LVL 16
61+ IntFloatImmutablePair .of (5 , 5.25f ), // LVL 17
62+ IntFloatImmutablePair .of (5 , 6.25f ), // LVL 18
63+ IntFloatImmutablePair .of (5 , 7.25f ), // LVL 19
64+ IntFloatImmutablePair .of (5 , 8.5f ) // LVL 20
6465 };
6566
6667 // General
@@ -113,14 +114,20 @@ public class Blur extends Module {
113114 );
114115
115116 private final GpuTextureView [] fbos = new GpuTextureView [6 ];
116- private boolean initialized ;
117+ private GpuBufferSlice [] ubos ;
117118
118119 private boolean enabled ;
119120 private long fadeEndAt ;
121+ private float previousOffset = -1 ;
120122
121123 public Blur () {
122124 super (Categories .Render , "blur" , "Blurs background when in GUI screens." );
123125
126+ // Initialize fbos for the first time
127+ for (int i = 0 ; i < fbos .length ; i ++) {
128+ fbos [i ] = createFbo (i );
129+ }
130+
124131 // The listeners need to run even when the module is not enabled
125132 MeteorClient .EVENT_BUS .subscribe (new ConsumerListener <>(ResolutionChangedEvent .class , event -> {
126133 // Resize all fbos
@@ -131,6 +138,9 @@ public Blur() {
131138
132139 fbos [i ] = createFbo (i );
133140 }
141+
142+ // Invalidate ubos
143+ previousOffset = -1 ;
134144 }));
135145
136146 MeteorClient .EVENT_BUS .subscribe (new ConsumerListener <>(RenderAfterWorldEvent .class , event -> onRenderAfterWorld ()));
@@ -168,17 +178,6 @@ private void onRenderAfterWorld() {
168178
169179 if (!enabled ) return ;
170180
171- // Initialize shader and framebuffer if running for the first time
172- if (!initialized ) {
173- for (int i = 0 ; i < fbos .length ; i ++) {
174- if (fbos [i ] == null ) {
175- fbos [i ] = createFbo (i );
176- }
177- }
178-
179- initialized = true ;
180- }
181-
182181 // Update progress
183182 double progress = 1 ;
184183
@@ -190,21 +189,27 @@ private void onRenderAfterWorld() {
190189 }
191190
192191 // Update strength
193- IntDoubleImmutablePair strength = strengths [(int ) ((this .strength .get () - 1 ) * progress )];
192+ IntFloatImmutablePair strength = strengths [(int ) ((this .strength .get () - 1 ) * progress )];
194193 int iterations = strength .leftInt ();
195- double offset = strength .rightDouble ();
194+ float offset = strength .rightFloat ();
195+
196+ // Update uniforms
197+ if (previousOffset != offset ) {
198+ updateUniforms (offset );
199+ previousOffset = offset ;
200+ }
196201
197202 // Initial downsample
198- renderToFbo (fbos [0 ], mc .getFramebuffer ().getColorAttachmentView (), MeteorRenderPipelines .BLUR_DOWN , offset );
203+ renderToFbo (fbos [0 ], mc .getFramebuffer ().getColorAttachmentView (), MeteorRenderPipelines .BLUR_DOWN , ubos [ 0 ] );
199204
200205 // Downsample
201206 for (int i = 0 ; i < iterations ; i ++) {
202- renderToFbo (fbos [i + 1 ], fbos [i ], MeteorRenderPipelines .BLUR_DOWN , offset );
207+ renderToFbo (fbos [i + 1 ], fbos [i ], MeteorRenderPipelines .BLUR_DOWN , ubos [ i + 1 ] );
203208 }
204209
205210 // Upsample
206211 for (int i = iterations ; i >= 1 ; i --) {
207- renderToFbo (fbos [i - 1 ], fbos [i ], MeteorRenderPipelines .BLUR_UP , offset );
212+ renderToFbo (fbos [i - 1 ], fbos [i ], MeteorRenderPipelines .BLUR_UP , ubos [ i - 1 ] );
208213 }
209214
210215 // Render output
@@ -216,7 +221,7 @@ private void onRenderAfterWorld() {
216221 .end ();
217222 }
218223
219- private void renderToFbo (GpuTextureView targetFbo , GpuTextureView sourceTexture , RenderPipeline pipeline , double offset ) {
224+ private void renderToFbo (GpuTextureView targetFbo , GpuTextureView sourceTexture , RenderPipeline pipeline , GpuBufferSlice ubo ) {
220225 AddressMode prevAddressModeU = ((IGpuTexture ) sourceTexture .texture ()).meteor$getAddressModeU ();
221226 AddressMode prevAddressModeV = ((IGpuTexture ) sourceTexture .texture ()).meteor$getAddressModeV ();
222227
@@ -225,11 +230,8 @@ private void renderToFbo(GpuTextureView targetFbo, GpuTextureView sourceTexture,
225230 MeshRenderer .begin ()
226231 .attachments (targetFbo , null )
227232 .pipeline (pipeline )
228- .uniform ("BlurData" , UNIFORM_STORAGE .write (new UniformData (
229- 0.5f / targetFbo .getWidth (0 ), 0.5f / targetFbo .getHeight (0 ),
230- (float ) offset
231- )))
232233 .fullscreen ()
234+ .uniform ("BlurData" , ubo )
233235 .sampler ("u_Texture" , sourceTexture )
234236 .end ();
235237
@@ -250,18 +252,29 @@ private boolean shouldRender() {
250252
251253 // Uniforms
252254
255+ private void updateUniforms (float offset ) {
256+ UNIFORM_STORAGE .clear ();
257+
258+ BlurUniformData [] uboData = new BlurUniformData [6 ];
259+ for (int i = 0 ; i < uboData .length ; i ++) {
260+ GpuTextureView fbo = fbos [i ];
261+ uboData [i ] = new BlurUniformData (
262+ 0.5f / fbo .getWidth (0 ), 0.5f / fbo .getHeight (0 ),
263+ offset
264+ );
265+ }
266+
267+ ubos = UNIFORM_STORAGE .writeAll (uboData );
268+ }
269+
253270 private static final int UNIFORM_SIZE = new Std140SizeCalculator ()
254271 .putVec2 ()
255272 .putFloat ()
256273 .get ();
257274
258- private static final DynamicUniformStorage <UniformData > UNIFORM_STORAGE = new DynamicUniformStorage <>("Meteor - Blur UBO" , UNIFORM_SIZE , 16 );
259-
260- public static void flipFrame () {
261- UNIFORM_STORAGE .clear ();
262- }
275+ private static final FixedUniformStorage <BlurUniformData > UNIFORM_STORAGE = new FixedUniformStorage <>("Meteor - Blur UBO" , UNIFORM_SIZE , 6 );
263276
264- private record UniformData (float halfTexelSizeX , float halfTexelSizeY , float offset ) implements DynamicUniformStorage .Uploadable {
277+ private record BlurUniformData (float halfTexelSizeX , float halfTexelSizeY , float offset ) implements DynamicUniformStorage .Uploadable {
265278 @ Override
266279 public void write (ByteBuffer buffer ) {
267280 Std140Builder .intoBuffer (buffer )
0 commit comments