diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java index 3bed52112..dc257d94e 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -13,7 +13,6 @@ import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.InstanceType; import dev.engine_room.flywheel.api.material.Material; -import dev.engine_room.flywheel.api.material.Transparency; import dev.engine_room.flywheel.api.model.Model; import dev.engine_room.flywheel.backend.compile.ContextShader; import dev.engine_room.flywheel.backend.compile.IndirectPrograms; @@ -37,7 +36,8 @@ public class IndirectCullingGroup { private final IndirectBuffers buffers; private final List> instancers = new ArrayList<>(); private final List indirectDraws = new ArrayList<>(); - private final List multiDraws = new ArrayList<>(); + private final List solidDraws = new ArrayList<>(); + private final List translucentDraws = new ArrayList<>(); private final List oitDraws = new ArrayList<>(); private final IndirectPrograms programs; @@ -128,7 +128,8 @@ public boolean hasOitDraws() { } private void sortDraws() { - multiDraws.clear(); + solidDraws.clear(); + translucentDraws.clear(); oitDraws.clear(); // sort by visual type, then material indirectDraws.sort(DRAW_COMPARATOR); @@ -138,9 +139,17 @@ private void sortDraws() { // if the next draw call has a different VisualType or Material, start a new MultiDraw if (i == indirectDraws.size() - 1 || incompatibleDraws(draw1, indirectDraws.get(i + 1))) { - var dst = draw1.material() - .transparency() == Transparency.ORDER_INDEPENDENT ? oitDraws : multiDraws; - dst.add(new MultiDraw(draw1.material(), draw1.isEmbedded(), start, i + 1)); + + var material = draw1.material(); + var t = material.transparency(); + + List dst = switch (t) { + case ORDER_INDEPENDENT -> oitDraws; + case OPAQUE -> solidDraws; + default -> translucentDraws; + }; + + dst.add(new MultiDraw(material, draw1.isEmbedded(), start, i + 1)); start = i + 1; } } @@ -174,7 +183,15 @@ public void add(IndirectInstancer instancer, InstancerKey key, MeshPool me } public void submitSolid() { - if (multiDraws.isEmpty()) { + submit(solidDraws); + } + + public void submitTranslucent() { + submit(translucentDraws); + } + + private void submit(List draws) { + if (draws.isEmpty()) { return; } @@ -184,7 +201,7 @@ public void submitSolid() { GlProgram lastProgram = null; - for (var multiDraw : multiDraws) { + for (var multiDraw : draws) { var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material, PipelineCompiler.OitMode.OFF); if (drawProgram != lastProgram) { lastProgram = drawProgram; @@ -199,7 +216,7 @@ public void submitSolid() { } } - public void submitTransparent(PipelineCompiler.OitMode oit) { + public void submitOrderIndependent(PipelineCompiler.OitMode oit) { if (oitDraws.isEmpty()) { return; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java index 5211ba7a9..ebe179f6c 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -151,6 +151,10 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor group.submitSolid(); } + for (var group : cullingGroups.values()) { + group.submitTranslucent(); + } + // Let's avoid invoking the oit chain if we don't have anything to do boolean useOit = false; for (var group : cullingGroups.values()) { @@ -166,13 +170,13 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor oitFramebuffer.depthRange(); for (var group : cullingGroups.values()) { - group.submitTransparent(PipelineCompiler.OitMode.DEPTH_RANGE); + group.submitOrderIndependent(PipelineCompiler.OitMode.DEPTH_RANGE); } oitFramebuffer.renderTransmittance(); for (var group : cullingGroups.values()) { - group.submitTransparent(PipelineCompiler.OitMode.GENERATE_COEFFICIENTS); + group.submitOrderIndependent(PipelineCompiler.OitMode.GENERATE_COEFFICIENTS); } oitFramebuffer.renderDepthFromTransmittance(); @@ -183,7 +187,7 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor oitFramebuffer.accumulate(); for (var group : cullingGroups.values()) { - group.submitTransparent(PipelineCompiler.OitMode.EVALUATE); + group.submitOrderIndependent(PipelineCompiler.OitMode.EVALUATE); } oitFramebuffer.composite();