Skip to content

Commit 242cc99

Browse files
committed
- 修复 Forge 上部分光影粒子透明
- 修复粒子雨计数错误的问题 - 修复自定义类型粒子不渲染 - 修复 Forge 上部分不应剔除的粒子被剔除 - 尝试兼容 particlecore - 添加选项 markSyncIfTickFailed 在粒子tick失败时标记为同步tick(默认不启用) - 添加选项 ignoreParticleTickExceptions 忽略粒子tick时的所有异常(默认不启用) - 添加选项 greedyAsyncClientBlockEntityTick 更激进的异步客户端方块刻(默认不启用) - 添加选项 asyncClientBlockEntityAnimate 异步方块动画刻(默认启用)
1 parent 6c1dc6a commit 242cc99

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+957
-195
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
## Features
66

7-
- Vanilla Minecraft
8-
- Async ticking/rendering of particles.
7+
- Minecraft
8+
- Async particle ticking/rendering(buffer filling).
99
- Async client block entity ticking.
1010
- Valkyrien Skies + Pretty Rain/Particle Rain
1111
- Weather particles no longer pass through ships.
@@ -33,7 +33,6 @@
3333

3434
### Mods Tested
3535

36-
❔ Create (Fabric/Forge)
3736
✅ Forge + Sinytra Connector
3837
✅ Fabric
3938
✅ ModernFix (Fabric/Forge)
@@ -42,6 +41,7 @@
4241
✅ Brute force Rendering Culling (Fabric/Forge)
4342
✅ Iris/Oculus (Fabric/Forge)
4443
✅ Startlight (Fabric/Forge)
44+
❔ Create (Fabric/Forge)
4545
✅ Valkyrien Skies (Fabric/Forge)
4646
✅ Particle Rain/Pretty Rain (Fabric/Forge)
4747
✅ Effectual (Fabric)

build.gradle

+4-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ subprojects {
6666
name = "Ladysnake Mods"
6767
url = 'https://maven.ladysnake.org/releases'
6868
}
69-
69+
maven { // conditional-mixin (particlecore)
70+
name = "FallenBreath"
71+
url = uri("https://maven.fallenbreath.me/releases")
72+
}
7073
}
7174

7275
dependencies {

common/build.gradle

+6
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,10 @@ dependencies {
5858

5959
/* Particular */
6060
modCompileOnly "maven.modrinth:particular:1.1.1"
61+
62+
/* Particle Core */
63+
// modCompileOnly "maven.modrinth:particle-core:0.2.5+1.20.1"
64+
65+
/* Physics Mod */
66+
modCompileOnly fileTree(dir: '../libs', include: 'physics-mod-pro-v171b-fabric-1.20.1.jar')
6167
}

common/src/main/java/fun/qu_an/minecraft/asyncparticles/client/APMixinPlugin.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fun.qu_an.minecraft.asyncparticles.client;
22

33
import com.bawnorton.mixinsquared.canceller.MixinCancellerRegistrar;
4+
import net.minecraft.client.renderer.texture.AbstractTexture;
45
import org.objectweb.asm.tree.ClassNode;
56
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
67
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@@ -13,7 +14,18 @@ public class APMixinPlugin implements IMixinConfigPlugin {
1314
public void onLoad(String mixinPackage) {
1415
MixinCancellerRegistrar.register((targetClassNames, mixinClassName)
1516
-> switch (mixinClassName) {
16-
case "net.irisshaders.iris.mixin.fantastic.MixinLevelRenderer" -> true;
17+
case "net.irisshaders.iris.mixin.fantastic.MixinLevelRenderer",
18+
// o(≧口≦)o particle_core: These mixins not support async rendering
19+
"me.fzzyhmstrs.particle_core.mixins.ParticleManagerFrustumMixin",
20+
"me.fzzyhmstrs.particle_core.mixins.ParticleManagerRotationMixin",
21+
"me.fzzyhmstrs.particle_core.mixins.WorldRendererFrustumMixin",
22+
"me.fzzyhmstrs.particle_core.mixins.ParticleManagerCachedLightMixin",
23+
"me.fzzyhmstrs.particle_core.mixins.BillboardParticleMixin",
24+
"me.fzzyhmstrs.particle_core.mixins.ParticleMixin",
25+
"com.moepus.flerovium.mixins.Particle.ParticleEngineMixin",
26+
"com.moepus.flerovium.mixins.Particle.ParticleMixin"
27+
// , "net.diebuddies.mixins.ocean.MixinParticleEngine"
28+
-> true;
1729
default -> false;
1830
});
1931
}
@@ -27,6 +39,9 @@ public String getRefMapperConfig() {
2739
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
2840
String mixinPackageName = mixinClassName.substring("fun.qu_an.minecraft.asyncparticles.client.mixin.".length());
2941
String[] split = mixinPackageName.split("\\.");
42+
if (split.length == 1) {
43+
return true;
44+
}
3045
return switch (split[0]) {
3146
case "fabric" -> {
3247
if (split.length <= 2) {
@@ -42,14 +57,17 @@ yield switch (split[1]) {
4257
default -> throw new IllegalArgumentException("Unknown fabric mixin: " + mixinClassName);
4358
};
4459
}
60+
case "fake_renders" -> true;
4561
case "vs2" -> ModListHelper.VS_LOADED;
4662
case "iris" -> ModListHelper.IRIS_LOADED;
4763
case "sodium" -> ModListHelper.SODIUM_LOADED;
4864
case "lodestone" -> ModListHelper.LODESTONE_LOADED;
4965
case "hexcasting" -> ModListHelper.HEXCASTING_LOADED;
5066
case "flywheel" -> ModListHelper.FLYWHEEL_LOADED;
67+
case "particle_core" -> ModListHelper.PARTICLE_CORE_LOADED;
68+
case "physicsmod" -> ModListHelper.PHYSICSMOD_LOADED;
5169
// case "enhancedblockentities" -> ModListHelper.ENHANCEDBLOCKENTITIES_LOADED;
52-
default -> true;
70+
default -> throw new IllegalArgumentException("Unknown mixin: " + mixinClassName);
5371
};
5472
}
5573

common/src/main/java/fun/qu_an/minecraft/asyncparticles/client/AsyncRenderer.java

+36-30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.mojang.blaze3d.vertex.VertexFormat;
77
import com.mojang.logging.LogUtils;
88
import fun.qu_an.minecraft.asyncparticles.client.config.SimplePropertiesConfig;
9+
import fun.qu_an.minecraft.asyncparticles.client.util.FakeBeginBufferBuilder;
910
import fun.qu_an.minecraft.asyncparticles.client.util.FakeBufferBuilder;
1011
import fun.qu_an.minecraft.asyncparticles.client.util.FakeTesselator;
1112
import it.unimi.dsi.fastutil.Pair;
@@ -24,14 +25,14 @@
2425
import net.minecraft.util.Mth;
2526
import net.minecraft.util.profiling.ProfilerFiller;
2627
import org.jetbrains.annotations.NotNull;
27-
import org.jetbrains.annotations.Nullable;
2828
import org.slf4j.Logger;
2929

3030
import java.util.*;
3131
import java.util.concurrent.*;
3232
import java.util.concurrent.atomic.AtomicInteger;
3333
import java.util.function.Consumer;
3434

35+
// TODO: 整理这一坨
3536
public class AsyncRenderer {
3637
private static final Logger LOGGER = LogUtils.getLogger();
3738
private static final Set<Class<? extends Particle>> SYNC_PARTICLE_TYPES = Collections.newSetFromMap(new IdentityHashMap<>());
@@ -73,6 +74,16 @@ public class AsyncRenderer {
7374
LOGGER.error("", e);
7475
}
7576
}
77+
if (ModListHelper.PHYSICSMOD_LOADED) {
78+
try {
79+
addSyncByClassName("net.diebuddies.minecraft.weather.RainParticle");
80+
addSyncByClassName("net.diebuddies.minecraft.weather.DustParticle");
81+
addSyncByClassName("net.diebuddies.minecraft.weather.SnowParticle");
82+
addSyncByClassName("net.diebuddies.physics.ocean.RainParticle");
83+
} catch (Exception e) {
84+
LOGGER.error("", e);
85+
}
86+
}
7687
// TODO: configure this set
7788
}
7889

@@ -118,6 +129,8 @@ protected void onTermination(Throwable throwable) {
118129
public static boolean isStart;
119130
private static CompletableFuture<Void> asyncTask;
120131

132+
/* Renderer */
133+
121134
public static void add(Runnable task) {
122135
ASYNC_QUEUE.add(task);
123136
}
@@ -141,7 +154,10 @@ public static void start(PoseStack poseStack, float f, Camera camera, LightTextu
141154
futures[i] = CompletableFuture.runAsync(runnable, EXECUTOR)
142155
.exceptionally(e -> {
143156
LOGGER.error("Error rendering particle", e);
144-
throw new RuntimeException(e);
157+
if (mc.level != null && mc.player != null){
158+
throw new RuntimeException(e);
159+
}
160+
return null;
145161
});
146162
}
147163
ASYNC_QUEUE.clear();
@@ -166,15 +182,9 @@ public static void irisOpaque(PoseStack poseStack, float f, Camera camera, Light
166182
isStart = false;
167183
MultiBufferSource.BufferSource bufferSource = levelRenderer.renderBuffers.bufferSource();
168184

169-
// if (ModListHelper.IRIS_LOADED) {
170-
// if (getRenderingSettings() == ParticleRenderingSettings.MIXED) {
171-
172185
ParticleEngine particleEngine = mc.particleEngine;
173186
((PhasedParticleEngine) particleEngine).setParticleRenderingPhase(ParticleRenderingPhase.OPAQUE);
174187
particleEngine.render(poseStack, bufferSource, lightTexture, camera, f);
175-
176-
// }
177-
// }
178188
}
179189

180190
public static void irisTranslucent(PoseStack poseStack, float f, Camera camera, LightTexture lightTexture) {
@@ -186,21 +196,10 @@ public static void irisTranslucent(PoseStack poseStack, float f, Camera camera,
186196
LevelRenderer levelRenderer = mc.levelRenderer;
187197
MultiBufferSource.BufferSource bufferSource = levelRenderer.renderBuffers.bufferSource();
188198

189-
// if (ModListHelper.IRIS_LOADED) {
190-
// if (getRenderingSettings() == ParticleRenderingSettings.MIXED) {
191-
192199
ParticleEngine particleEngine = mc.particleEngine;
193200
((PhasedParticleEngine) particleEngine).setParticleRenderingPhase(ParticleRenderingPhase.TRANSLUCENT);
194201
particleEngine.render(poseStack, bufferSource, lightTexture, camera, f);
195202

196-
// } else {
197-
// ((PhasedParticleEngine) mc.particleEngine).setParticleRenderingPhase(ParticleRenderingPhase.EVERYTHING);
198-
// mc.particleEngine.render(poseStack, bufferSource, lightTexture, camera, f);
199-
// }
200-
// } else {
201-
// mc.particleEngine.render(poseStack, bufferSource, lightTexture, camera, f);
202-
// }
203-
204203
if (levelRenderer.transparencyChain != null) {
205204
RenderStateShard.PARTICLES_TARGET.clearRenderState();
206205
}
@@ -241,25 +240,22 @@ private static ParticleRenderingSettings getRenderingSettings() {
241240

242241
private static BufferBuilder getBufferBuilder(ParticleRenderType particleRenderType) {
243242
return BUFFER_BUILDERS.computeIfAbsent(particleRenderType,
244-
k -> {
245-
// if (k != ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT) {
246-
// return new ThreadLocalBufferBuilder(RenderType.SMALL_BUFFER_SIZE, ForkJoinPool.getCommonPoolParallelism());
247-
// }
248-
return new BufferBuilder(RenderType.SMALL_BUFFER_SIZE / 2);
249-
}); // 给多大好?
243+
k -> new BufferBuilder(RenderType.SMALL_BUFFER_SIZE / 2)); // 给多大好?
250244
}
251245

246+
/* BufferBuilder */
247+
252248
private static final Map<ParticleRenderType, Pair<VertexFormat.Mode, VertexFormat>> FORMATS = new IdentityHashMap<>();
253249
private static final Pair<VertexFormat.Mode, VertexFormat> EMPTY_FORMAT = Pair.of(null, null);
254250

255-
public static @Nullable BufferBuilder beginBufferBuilder(ParticleRenderType particleRenderType, TextureManager textureManager) {
251+
public static BufferBuilder beginBufferBuilder(ParticleRenderType particleRenderType, TextureManager textureManager) {
256252
BufferBuilder builder = getBufferBuilder(particleRenderType);
257253
if (builder.building()) {
258254
return builder;
259255
}
260256
Pair<VertexFormat.Mode, VertexFormat> pair = FORMATS.computeIfAbsent(particleRenderType, k -> computeVertexFormatPair(k, textureManager));
261257
if (pair == EMPTY_FORMAT) {
262-
return null;
258+
return FakeBeginBufferBuilder.INSTANCE;
263259
}
264260
builder.begin(pair.first(), pair.second());
265261
return builder;
@@ -291,6 +287,8 @@ public static boolean begin(ParticleRenderType particleRenderType, TextureManage
291287
return Pair.of(mode, format);
292288
}
293289

290+
/* Sync Rendering */
291+
294292
public static void markAsSync(Class<? extends Particle> aClass) {
295293
synchronized (SYNC_PARTICLE_TYPES) {
296294
SYNC_PARTICLE_TYPES.add(aClass);
@@ -314,9 +312,11 @@ public static List<? extends Particle> getSync(ParticleRenderType particleRender
314312
}
315313

316314
private static void clearSync() {
317-
SYNC_PARTICLES.clear();
315+
SYNC_PARTICLES.values().forEach(List::clear);
318316
}
319317

318+
/* Debug */
319+
320320
public static void debugLater(Consumer<String> consumer) {
321321
debugConsumer = consumer;
322322
}
@@ -327,19 +327,25 @@ private static void tryDebug() {
327327
[Debug AsyncRenderer]
328328
async queue size: %d,
329329
sync particle count: %d,
330-
sync particle types: %s"""
330+
sync particle types: %s,
331+
iris particle state: %s"""
331332
.formatted(ASYNC_QUEUE.size(),
332333
SYNC_PARTICLES.values().stream().mapToInt(List::size).sum(),
333-
SYNC_PARTICLE_TYPES.stream().map(Class::getName).toList()));
334+
SYNC_PARTICLE_TYPES.stream().map(Class::getName).toList(),
335+
ModListHelper.IRIS_LOADED && Iris.isPackInUseQuick() ? getRenderingSettings().name() : "disabled"));
334336
debugConsumer = null;
335337
}
336338
}
337339

340+
/* Config */
341+
338342
public static boolean forceSyncLevelRenderMarkDirty() {
339343
// TODO: 详细看看 EBE Mod
340344
return ModListHelper.ENHANCEDBLOCKENTITIES_LOADED || SimplePropertiesConfig.forceSyncLevelRenderMarkDirty;
341345
}
342346

347+
/* Destroy */
348+
343349
public static void destroy() {
344350
if (asyncTask != null) {
345351
// 应该不会到这里

0 commit comments

Comments
 (0)