diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java index 8da5010e3..11e375668 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java @@ -39,46 +39,22 @@ public final class FlwPrograms { var vertexComponentsHeader = loader.find(COMPONENTS_HEADER_VERT); var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG); - // TODO: de-uber material shaders - var vertexMaterialComponent = createVertexMaterialComponent(loader); - var fragmentMaterialComponent = createFragmentMaterialComponent(loader); var fogComponent = createFogComponent(loader); - // TODO: separate compilation for cutout OFF, but keep the rest uber'd - var cutoutComponent = createCutoutComponent(loader); - if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || vertexMaterialComponent == null || fragmentMaterialComponent == null || fogComponent == null || cutoutComponent == null) { + // TODO: separate compilation for cutout OFF, but keep the rest uber'd? + if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || fogComponent == null) { // Probably means the shader sources are missing. stats.emitErrorLog(); return; } - List vertexComponents = List.of(vertexComponentsHeader, vertexMaterialComponent); - List fragmentComponents = List.of(fragmentComponentsHeader, fragmentMaterialComponent, fogComponent, cutoutComponent); + List vertexComponents = List.of(vertexComponentsHeader); + List fragmentComponents = List.of(fragmentComponentsHeader, fogComponent); InstancingPrograms.reload(sources, vertexComponents, fragmentComponents); IndirectPrograms.reload(sources, vertexComponents, fragmentComponents); } - @Nullable - private static UberShaderComponent createVertexMaterialComponent(SourceLoader loader) { - return UberShaderComponent.builder(Flywheel.rl("material_vertex")) - .materialSources(MaterialShaderIndices.vertexSources() - .all()) - .adapt(FnSignature.ofVoid("flw_materialVertex")) - .switchOn(GlslExpr.variable("_flw_uberMaterialVertexIndex")) - .build(loader); - } - - @Nullable - private static UberShaderComponent createFragmentMaterialComponent(SourceLoader loader) { - return UberShaderComponent.builder(Flywheel.rl("material_fragment")) - .materialSources(MaterialShaderIndices.fragmentSources() - .all()) - .adapt(FnSignature.ofVoid("flw_materialFragment")) - .switchOn(GlslExpr.variable("_flw_uberMaterialFragmentIndex")) - .build(loader); - } - @Nullable private static UberShaderComponent createFogComponent(SourceLoader loader) { return UberShaderComponent.builder(Flywheel.rl("fog")) diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java index ba226541e..524a1b583 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java @@ -8,7 +8,9 @@ import com.google.common.collect.ImmutableList; import dev.engine_room.flywheel.api.Flywheel; import dev.engine_room.flywheel.api.instance.InstanceType; +import dev.engine_room.flywheel.api.material.CutoutShader; import dev.engine_room.flywheel.api.material.LightShader; +import dev.engine_room.flywheel.api.material.MaterialShaders; import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent; import dev.engine_room.flywheel.backend.compile.component.SsboInstanceComponent; import dev.engine_room.flywheel.backend.compile.core.CompilationHarness; @@ -148,8 +150,8 @@ public class IndirectPrograms extends AtomicReferenceCounted { setInstance(null); } - public GlProgram getIndirectProgram(InstanceType instanceType, ContextShader contextShader, LightShader light) { - return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light)); + public GlProgram getIndirectProgram(InstanceType instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders shaders) { + return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders)); } public GlProgram getCullingProgram(InstanceType instanceType) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java index e63c80955..ac9de915d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java @@ -7,7 +7,9 @@ import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; import dev.engine_room.flywheel.api.instance.InstanceType; +import dev.engine_room.flywheel.api.material.CutoutShader; import dev.engine_room.flywheel.api.material.LightShader; +import dev.engine_room.flywheel.api.material.MaterialShaders; import dev.engine_room.flywheel.backend.compile.core.CompilationHarness; import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; @@ -71,8 +73,8 @@ public class InstancingPrograms extends AtomicReferenceCounted { setInstance(null); } - public GlProgram get(InstanceType instanceType, ContextShader contextShader, LightShader light) { - return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light)); + public GlProgram get(InstanceType instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders materialShaders) { + return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders)); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java index 405ca7ffe..10e443f16 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java @@ -35,9 +35,11 @@ public final class PipelineCompiler { var instance = ResourceUtil.toDebugFileNameNoExtension(key.instanceType() .vertexShader()); + var material = ResourceUtil.toDebugFileNameNoExtension(key.materialShaders() + .vertexSource()); var context = key.contextShader() .nameLowerCase(); - return "pipeline/" + pipeline.compilerMarker() + "/" + instance + "_" + context; + return "pipeline/" + pipeline.compilerMarker() + "/" + instance + "/" + material + "_" + context; }) .requireExtensions(extensions) .onCompile((key, comp) -> key.contextShader() @@ -47,6 +49,8 @@ public final class PipelineCompiler { .withComponent(key -> new InstanceStructComponent(key.instanceType())) .withResource(key -> key.instanceType() .vertexShader()) + .withResource(key -> key.materialShaders() + .vertexSource()) .withComponents(vertexComponents) .withResource(InternalVertex.LAYOUT_SHADER) .withComponent(key -> pipeline.assembler() @@ -56,8 +60,16 @@ public final class PipelineCompiler { .nameMapper(key -> { var context = key.contextShader() .nameLowerCase(); - return "pipeline/" + pipeline.compilerMarker() + "/" + ResourceUtil.toDebugFileNameNoExtension(key.light() - .source()) + "_" + context; + + var material = ResourceUtil.toDebugFileNameNoExtension(key.materialShaders() + .fragmentSource()); + + var cutout = ResourceUtil.toDebugFileNameNoExtension(key.cutout() + .source()); + + var light = ResourceUtil.toDebugFileNameNoExtension(key.light() + .source()); + return "pipeline/" + pipeline.compilerMarker() + "/frag/" + material + "/" + light + "_" + cutout + "_" + context; }) .requireExtensions(extensions) .enableExtension("GL_ARB_conservative_depth") @@ -65,9 +77,13 @@ public final class PipelineCompiler { .onCompile(comp)) .onCompile((key, comp) -> lightSmoothness.onCompile(comp)) .withResource(API_IMPL_FRAG) + .withResource(key -> key.materialShaders() + .fragmentSource()) .withComponents(fragmentComponents) .withResource(key -> key.light() .source()) + .withResource(key -> key.cutout() + .source()) .withResource(pipeline.fragmentMain())) .preLink((key, program) -> { program.bindAttribLocation("_flw_aPos", 0); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineProgramKey.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineProgramKey.java index 3fe6a1033..bd8d0a1a2 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineProgramKey.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineProgramKey.java @@ -1,7 +1,9 @@ package dev.engine_room.flywheel.backend.compile; import dev.engine_room.flywheel.api.instance.InstanceType; +import dev.engine_room.flywheel.api.material.CutoutShader; import dev.engine_room.flywheel.api.material.LightShader; +import dev.engine_room.flywheel.api.material.MaterialShaders; /** * Represents the entire context of a program's usage. @@ -10,5 +12,6 @@ import dev.engine_room.flywheel.api.material.LightShader; * @param contextShader The context shader to use. * @param light The light shader to use. */ -public record PipelineProgramKey(InstanceType instanceType, ContextShader contextShader, LightShader light) { +public record PipelineProgramKey(InstanceType instanceType, ContextShader contextShader, LightShader light, + CutoutShader cutout, MaterialShaders materialShaders) { } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java index 0ba79b486..3375ecf2d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java @@ -12,12 +12,14 @@ import java.util.function.Function; import org.jetbrains.annotations.Nullable; +import dev.engine_room.flywheel.backend.compile.FlwPrograms; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlShader; import dev.engine_room.flywheel.backend.gl.shader.ShaderType; import dev.engine_room.flywheel.backend.glsl.GlslVersion; import dev.engine_room.flywheel.backend.glsl.ShaderSources; import dev.engine_room.flywheel.backend.glsl.SourceComponent; +import dev.engine_room.flywheel.lib.util.StringUtil; import net.minecraft.resources.ResourceLocation; /** @@ -122,6 +124,8 @@ public class Compile { @Nullable private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) { + long start = System.nanoTime(); + var components = new ArrayList(); boolean ok = true; for (var fetcher : fetchers) { @@ -137,7 +141,14 @@ public class Compile { } Consumer cb = ctx -> compilationCallbacks.accept(key, ctx); - return compiler.compile(glslVersion, shaderType, nameMapper.apply(key), cb, components); + var name = nameMapper.apply(key); + var out = compiler.compile(glslVersion, shaderType, name, cb, components); + + long end = System.nanoTime(); + + FlwPrograms.LOGGER.debug("Compiled {} in {}", name, StringUtil.formatTime(end - start)); + + return out; } } @@ -177,6 +188,8 @@ public class Compile { throw new IllegalStateException("No shader compilers were added!"); } + long start = System.nanoTime(); + List shaders = new ArrayList<>(); boolean ok = true; @@ -198,6 +211,10 @@ public class Compile { postLink.accept(key, out); } + long end = System.nanoTime(); + + FlwPrograms.LOGGER.debug("Linked {} in {}", key, StringUtil.formatTime(end - start)); + return out; } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java index de3661703..893cbdeab 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java @@ -5,6 +5,7 @@ import dev.engine_room.flywheel.api.material.Transparency; import dev.engine_room.flywheel.api.material.WriteMask; import dev.engine_room.flywheel.lib.material.CutoutShaders; import dev.engine_room.flywheel.lib.material.FogShaders; +import dev.engine_room.flywheel.lib.material.LightShaders; import dev.engine_room.flywheel.lib.material.SimpleMaterial; public class CommonCrumbling { @@ -12,6 +13,7 @@ public class CommonCrumbling { crumblingMaterial.copyFrom(baseMaterial) .fog(FogShaders.NONE) .cutout(CutoutShaders.ONE_TENTH) + .light(LightShaders.SMOOTH_WHEN_EMBEDDED) .polygonOffset(true) .transparency(Transparency.CRUMBLING) .writeMask(WriteMask.COLOR) 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 c12277860..42511d84a 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 @@ -26,7 +26,6 @@ import dev.engine_room.flywheel.backend.engine.MeshPool; import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; -import dev.engine_room.flywheel.lib.material.LightShaders; import dev.engine_room.flywheel.lib.math.MoreMath; public class IndirectCullingGroup { @@ -204,7 +203,7 @@ public class IndirectCullingGroup { int baseDrawUniformLoc = -1; for (var multiDraw : multiDraws.get(visualType)) { - var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light()); + var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light(), multiDraw.material.cutout(), multiDraw.material.shaders()); if (drawProgram != lastProgram) { lastProgram = drawProgram; @@ -221,8 +220,8 @@ public class IndirectCullingGroup { } } - public void bindWithContextShader(ContextShader override) { - var program = programs.getIndirectProgram(instanceType, override, LightShaders.SMOOTH_WHEN_EMBEDDED); + public void bindWithContextShader(ContextShader override, Material material) { + var program = programs.getIndirectProgram(instanceType, override, material.light(), material.cutout(), material.shaders()); program.bind(); 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 ac6093e47..bb8b8290b 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 @@ -216,8 +216,6 @@ public class IndirectDrawManager extends DrawManager> { continue; } - cullingGroup.bindWithContextShader(ContextShader.CRUMBLING); - for (var progressEntry : byProgress.int2ObjectEntrySet()) { Samplers.CRUMBLING.makeActive(); TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); @@ -230,6 +228,8 @@ public class IndirectDrawManager extends DrawManager> { // Transform the material to be suited for crumbling. CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material()); + cullingGroup.bindWithContextShader(ContextShader.CRUMBLING, crumblingMaterial); + MaterialRenderState.setup(crumblingMaterial); // Upload the draw command. diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java index 2e5c07e28..3db48d8a9 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java @@ -28,7 +28,6 @@ import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; import dev.engine_room.flywheel.backend.gl.TextureBuffer; import dev.engine_room.flywheel.backend.gl.array.GlVertexArray; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; -import dev.engine_room.flywheel.lib.material.LightShaders; import dev.engine_room.flywheel.lib.material.SimpleMaterial; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelBakery; @@ -169,9 +168,6 @@ public class InstancedDrawManager extends DrawManager> { GroupKey shader = groupEntry.getKey(); - var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, LightShaders.SMOOTH_WHEN_EMBEDDED); - program.bind(); - for (var progressEntry : byProgress.int2ObjectEntrySet()) { Samplers.CRUMBLING.makeActive(); TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); @@ -180,10 +176,11 @@ public class InstancedDrawManager extends DrawManager> { InstancedInstancer instancer = instanceHandlePair.getFirst(); var index = instanceHandlePair.getSecond().index; - program.setInt("_flw_baseInstance", index); - for (InstancedDraw draw : instancer.draws()) { CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material()); + var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial.light(), crumblingMaterial.cutout(), crumblingMaterial.shaders()); + program.bind(); + program.setInt("_flw_baseInstance", index); uploadMaterialUniform(program, crumblingMaterial); MaterialRenderState.setup(crumblingMaterial); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedRenderStage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedRenderStage.java index 73b1fdddf..572d9c573 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedRenderStage.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedRenderStage.java @@ -55,14 +55,13 @@ public class InstancedRenderStage { var environment = shader.environment(); for (var drawCall : drawCalls.draws) { - var program = programs.get(shader.instanceType(), environment.contextShader(), drawCall.material() - .light()); + var material = drawCall.material(); + + var program = programs.get(shader.instanceType(), environment.contextShader(), material.light(), material.cutout(), material.shaders()); program.bind(); environment.setupDraw(program); - var material = drawCall.material(); - uploadMaterialUniform(program, material); MaterialRenderState.setup(material);