fabric icon indicating copy to clipboard operation
fabric copied to clipboard

Add support for custom particle render layers

Open williewillus opened this issue 5 years ago • 6 comments

ParticleTextureSheet defines the GL state particles are rendered under (it's basically an older and way more primitive version of RenderLayer for particles)

In ParticleManager.renderParticles, vanilla iterates over a final immutable list of layers, instead of using the Map<ParticleTextureSheet, Queue<Particle>>'s keyset (and skipping NO_RENDER)

It would be convenient for modders with custom particle render types (like Botania) if a mixin could be added to iterate over the keyset instead of the final immutable list. Such a mixin would be small and be the only fix that is needed, vanilla handles everything else already.

As for why this needs to be in FAPI:

  • It's small
  • All modders with custom particle GL state need it
  • Multiple modders doing this same fix could be catastrophous (render particles multiple times)
  • Adding to the final immutable list is dirty and inconvenient.

williewillus avatar Jul 12 '20 15:07 williewillus

I can see the benefit of this. I would like to see RenderLayer abstracted just a little bit, perhaps with some kind of builder.

In your use case, are you using a custom RenderLayer or manipulating Gl state directly?

grondag avatar Jul 13 '20 03:07 grondag

all particle render layers manipulate GL state directly (See implementations of ParticleTextureSheet in vanilla)

At the moment I do the same.

williewillus avatar Jul 13 '20 14:07 williewillus

Fixing this issue is really just a matter of replacing the iterator in ParticleManager.renderParticles like this:

@Mixin(ParticleManager.class)
public class ParticleRenderFix {

    @Final
    @Shadow
    private Map<ParticleTextureSheet, Queue<Particle>> particles;

    @ModifyVariable(method="renderParticles", at=@At("STORE"), ordinal = 0)
    private Iterator<ParticleTextureSheet> fixParticleTextureSheets(Iterator<ParticleTextureSheet> i){
        return this.particles.keySet().stream().toList().iterator();
    }
}

But I agree this should really just be part of the FAPI

jpchristie5848 avatar Apr 05 '23 16:04 jpchristie5848

Feel free to PR it. :)

Technici4n avatar Apr 06 '23 07:04 Technici4n

5 years old and i still need it

Leclowndu93150 avatar Feb 03 '25 18:02 Leclowndu93150

It is not as simple as replacing the iterator as suggested because the map is unsorted and its key order is not guaranteed to match the vanilla order specified in PARTICLE_TEXTURE_SHEETS. NeoForge solves this by making the map sorted, but in such a way that the order of custom types is not deterministic between game startups and cannot be specified, which is not great in my opinion. Also, particles of the CUSTOM type are rendered separately after the for loop and particles of the NO_RENDER should not be rendered, so it is necessary to explicitly ignore these in the for loop if the keys are iterated over.

PepperCode1 avatar Feb 03 '25 18:02 PepperCode1