From d4426a5f6cf6fb0563b3928710e0ab2567355f74 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 2 Dec 2023 13:00:58 -0800 Subject: [PATCH] Looks good to me - Make SimpleMaterial.Builder implement Material itself. - Add way to copy a material. - Move fog/cutout shaders to their own utility classes. - Fix crumbling on cutout materials by overriding properties. - Add helper in glsl for unpacking 2 shorts from one uint. - Remove Fog enum. --- .../java/com/jozufozu/flywheel/Flywheel.java | 4 + .../jozufozu/flywheel/api/material/Fog.java | 16 -- .../engine/indirect/IndirectBuffers.java | 8 +- .../engine/instancing/InstancedCrumbling.java | 28 +++- .../flywheel/lib/material/CutoutShaders.java | 28 ++++ .../flywheel/lib/material/FogShaders.java | 19 +++ .../flywheel/lib/material/Materials.java | 14 +- .../flywheel/lib/material/SimpleMaterial.java | 138 ++++++++++++++++-- .../lib/material/StandardMaterialShaders.java | 18 --- .../flywheel/flywheel/context/crumbling.frag | 3 + .../flywheel/internal/indirect/draw.frag | 3 +- .../flywheel/internal/instancing/draw.frag | 3 +- .../flywheel/flywheel/internal/material.glsl | 5 + 13 files changed, 214 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/api/material/Fog.java create mode 100644 src/main/java/com/jozufozu/flywheel/lib/material/CutoutShaders.java create mode 100644 src/main/java/com/jozufozu/flywheel/lib/material/FogShaders.java diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index a17983a43..3f3c81902 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -22,6 +22,8 @@ import com.jozufozu.flywheel.impl.visualization.VisualizationEventHandler; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.instance.InstanceTypes; import com.jozufozu.flywheel.lib.light.LightUpdater; +import com.jozufozu.flywheel.lib.material.CutoutShaders; +import com.jozufozu.flywheel.lib.material.FogShaders; import com.jozufozu.flywheel.lib.material.StandardMaterialShaders; import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker; import com.jozufozu.flywheel.lib.model.ModelCache; @@ -129,6 +131,8 @@ public class Flywheel { private static void onClientSetup(FMLClientSetupEvent event) { VertexTypes.init(); InstanceTypes.init(); + CutoutShaders.init(); + FogShaders.init(); StandardMaterialShaders.init(); Contexts.init(); diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Fog.java b/src/main/java/com/jozufozu/flywheel/api/material/Fog.java deleted file mode 100644 index 31d441960..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/material/Fog.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.jozufozu.flywheel.api.material; - -public enum Fog { - /** - * Fade out to the fog color based on distance. - */ - LINEAR, - /** - * Fade out to black based on distance. - */ - LINEAR_FADE, - /** - * No fog. - */ - NONE, -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectBuffers.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectBuffers.java index 686dd17e0..138967c23 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectBuffers.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectBuffers.java @@ -29,7 +29,7 @@ public class IndirectBuffers { public static final long PTR_SIZE = Pointer.POINTER_SIZE; // DRAW COMMAND - public static final long DRAW_COMMAND_STRIDE = 48; + public static final long DRAW_COMMAND_STRIDE = 52; public static final long DRAW_COMMAND_OFFSET = 0; // BITS @@ -109,7 +109,7 @@ public class IndirectBuffers { } void createObjectStorage(int objectCount) { - freeObjectStogare(); + freeObjectStorage(); var objectSize = objectStride * objectCount; var targetSize = INT_SIZE * objectCount; @@ -165,7 +165,7 @@ public class IndirectBuffers { FlwMemoryTracker._allocGPUMemory(maxDrawCount * DRAW_COMMAND_STRIDE); } - private void freeObjectStogare() { + private void freeObjectStorage() { FlwMemoryTracker._freeGPUMemory(maxObjectCount * objectStride); } @@ -199,7 +199,7 @@ public class IndirectBuffers { public void delete() { nglDeleteBuffers(BUFFER_COUNT, buffers.ptr()); buffers.free(); - freeObjectStogare(); + freeObjectStorage(); freeDrawStorage(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java index 427530f96..919769a21 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java @@ -10,12 +10,17 @@ import org.jetbrains.annotations.NotNull; import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.material.Transparency; +import com.jozufozu.flywheel.api.material.WriteMask; +import com.jozufozu.flywheel.backend.MaterialUtil; import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl; import com.jozufozu.flywheel.backend.engine.UniformBuffer; import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.jozufozu.flywheel.lib.context.Contexts; +import com.jozufozu.flywheel.lib.material.CutoutShaders; +import com.jozufozu.flywheel.lib.material.SimpleMaterial; import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; @@ -42,15 +47,20 @@ public class InstancedCrumbling { ShaderState shader = shaderStateEntry.getKey(); - var material = shader.material(); + var baseMaterial = shader.material(); + int diffuseTexture = getDiffuseTexture(baseMaterial); + + var crumblingMaterial = SimpleMaterial.from(baseMaterial) + .transparency(Transparency.CRUMBLING) + .writeMask(WriteMask.COLOR) + .polygonOffset(true) + .cutout(CutoutShaders.OFF); var program = InstancingPrograms.get() .get(shader.vertexType(), shader.instanceType(), Contexts.CRUMBLING); UniformBuffer.syncAndBind(program); - InstancingEngine.uploadMaterialIDUniform(program, material); - - int renderTex = getDiffuseTexture(material); + InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial); for (Int2ObjectMap.Entry> progressEntry : byProgress.int2ObjectEntrySet()) { var drawCalls = progressEntry.getValue(); @@ -59,17 +69,19 @@ public class InstancedCrumbling { continue; } - var crumblingType = ModelBakery.DESTROY_TYPES.get(progressEntry.getIntKey()); + crumblingMaterial.baseTexture(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); - crumblingType.setupRenderState(); + MaterialUtil.setup(crumblingMaterial); - RenderSystem.setShaderTexture(1, renderTex); + RenderSystem.setShaderTexture(1, diffuseTexture); GlTextureUnit.T1.makeActive(); - RenderSystem.bindTexture(renderTex); + RenderSystem.bindTexture(diffuseTexture); drawCalls.forEach(Runnable::run); } } + + MaterialUtil.reset(); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/CutoutShaders.java b/src/main/java/com/jozufozu/flywheel/lib/material/CutoutShaders.java new file mode 100644 index 000000000..10696b854 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/material/CutoutShaders.java @@ -0,0 +1,28 @@ +package com.jozufozu.flywheel.lib.material; + +import org.jetbrains.annotations.ApiStatus; + +import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.material.CutoutShader; + +public class CutoutShaders { + /** + * Do not discard any fragments based on alpha. + */ + public static final CutoutShader OFF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/off.glsl"))); + /** + * Discard fragments with alpha close to or equal to zero. + */ + public static final CutoutShader EPSILON = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/epsilon.glsl"))); + /** + * Discard fragments with alpha less than to 0.5. + */ + public static final CutoutShader HALF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/half.glsl"))); + + private CutoutShaders() { + } + + @ApiStatus.Internal + public static void init() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/FogShaders.java b/src/main/java/com/jozufozu/flywheel/lib/material/FogShaders.java new file mode 100644 index 000000000..9c23ae718 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/material/FogShaders.java @@ -0,0 +1,19 @@ +package com.jozufozu.flywheel.lib.material; + +import org.jetbrains.annotations.ApiStatus; + +import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.material.FogShader; + +public class FogShaders { + public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl"))); + public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl"))); + public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl"))); + + private FogShaders() { + } + + @ApiStatus.Internal + public static void init() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java index ffcbcd4d5..0289d2f42 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java @@ -37,26 +37,26 @@ public final class Materials { .build(); public static final Material CHUNK_CUTOUT_MIPPED_SHADED = SimpleMaterial.builder() - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.cutoutMipped()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_CUTOUT_MIPPED_UNSHADED = SimpleMaterial.builder() .diffuse(false) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.cutoutMipped()) .build(); public static final Material CHUNK_CUTOUT_SHADED = SimpleMaterial.builder() .mip(false) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.cutout()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_CUTOUT_UNSHADED = SimpleMaterial.builder() .diffuse(false) .mip(false) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.cutout()) .build(); @@ -73,14 +73,14 @@ public final class Materials { public static final Material CHUNK_TRIPWIRE_SHADED = SimpleMaterial.builder() .transparency(Transparency.TRANSLUCENT) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.tripwire()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_TRIPWIRE_UNSHADED = SimpleMaterial.builder() .diffuse(false) .transparency(Transparency.TRANSLUCENT) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(RenderType.tripwire()) .build(); @@ -93,7 +93,7 @@ public final class Materials { .baseTexture(Sheets.SHULKER_SHEET) .mip(false) .backfaceCull(false) - .cutout(StandardMaterialShaders.EPSILON) + .cutout(CutoutShaders.EPSILON) .fallbackRenderType(Sheets.shulkerBoxSheet()) .build(); public static final Material BELL = SimpleMaterial.builder() diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java index b62680b3a..0a460ee2e 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java @@ -50,6 +50,10 @@ public class SimpleMaterial implements Material { return new Builder(); } + public static Builder from(Material material) { + return new Builder(material); + } + @Override public MaterialShaders shaders() { return shaders; @@ -117,26 +121,58 @@ public class SimpleMaterial implements Material { @Override public WriteMask writeMask() { - return WriteMask.BOTH; + return writeMask; } - public static class Builder { - protected RenderType fallbackRenderType = RenderType.solid(); - protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {}; - protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT; - protected ResourceLocation baseTexture = InventoryMenu.BLOCK_ATLAS; - protected boolean diffuse = true; - protected boolean lighting = true; - protected boolean blur = false; - protected boolean backfaceCull = true; - protected boolean polygonOffset = false; - protected boolean mip = true; - protected FogShader fog = StandardMaterialShaders.LINEAR; - protected Transparency transparency = Transparency.OPAQUE; - protected CutoutShader cutout = StandardMaterialShaders.OFF; - protected WriteMask writeMask = WriteMask.BOTH; + public static class Builder implements Material { + protected RenderType fallbackRenderType; + protected MaterialVertexTransformer vertexTransformer; + protected MaterialShaders shaders; + protected ResourceLocation baseTexture; + protected boolean diffuse; + protected boolean lighting; + protected boolean blur; + protected boolean backfaceCull; + protected boolean polygonOffset; + protected boolean mip; + protected FogShader fog; + protected Transparency transparency; + protected CutoutShader cutout; + protected WriteMask writeMask; public Builder() { + fallbackRenderType = RenderType.solid(); + vertexTransformer = (vertexList, level) -> { + }; + shaders = StandardMaterialShaders.DEFAULT; + baseTexture = InventoryMenu.BLOCK_ATLAS; + diffuse = true; + lighting = true; + blur = false; + backfaceCull = true; + polygonOffset = false; + mip = true; + fog = FogShaders.LINEAR; + transparency = Transparency.OPAQUE; + cutout = CutoutShaders.OFF; + writeMask = WriteMask.BOTH; + } + + public Builder(Material material) { + fallbackRenderType = material.getFallbackRenderType(); + vertexTransformer = material.getVertexTransformer(); + shaders = material.shaders(); + baseTexture = material.baseTexture(); + diffuse = material.diffuse(); + lighting = material.lighting(); + blur = material.blur(); + backfaceCull = material.backfaceCull(); + polygonOffset = material.polygonOffset(); + mip = material.mip(); + fog = material.fog(); + transparency = material.transparency(); + cutout = material.cutout(); + writeMask = material.writeMask(); } public Builder fallbackRenderType(RenderType type) { @@ -209,6 +245,76 @@ public class SimpleMaterial implements Material { return this; } + @Override + public MaterialShaders shaders() { + return shaders; + } + + @Override + public RenderType getFallbackRenderType() { + return fallbackRenderType; + } + + @Override + public MaterialVertexTransformer getVertexTransformer() { + return vertexTransformer; + } + + @Override + public ResourceLocation baseTexture() { + return baseTexture; + } + + @Override + public boolean diffuse() { + return diffuse; + } + + @Override + public boolean lighting() { + return lighting; + } + + @Override + public boolean blur() { + return blur; + } + + @Override + public boolean backfaceCull() { + return backfaceCull; + } + + @Override + public boolean polygonOffset() { + return polygonOffset; + } + + @Override + public boolean mip() { + return mip; + } + + @Override + public FogShader fog() { + return fog; + } + + @Override + public Transparency transparency() { + return transparency; + } + + @Override + public CutoutShader cutout() { + return cutout; + } + + @Override + public WriteMask writeMask() { + return writeMask; + } + public SimpleMaterial build() { return new SimpleMaterial(this); } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java b/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java index 1b9efdae2..d11c81d1c 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java @@ -3,29 +3,11 @@ package com.jozufozu.flywheel.lib.material; import org.jetbrains.annotations.ApiStatus; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.api.material.CutoutShader; -import com.jozufozu.flywheel.api.material.FogShader; import com.jozufozu.flywheel.api.material.MaterialShaders; import net.minecraft.resources.ResourceLocation; public final class StandardMaterialShaders { - /** - * Do not discard any fragments based on alpha. - */ - public static final CutoutShader OFF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/off.glsl"))); - /** - * Discard fragments with alpha close to or equal to zero. - */ - public static final CutoutShader EPSILON = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/epsilon.glsl"))); - /** - * Discard fragments with alpha less than to 0.5. - */ - public static final CutoutShader HALF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/half.glsl"))); - - public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl"))); - public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl"))); - public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl"))); public static final MaterialShaders DEFAULT = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.DEFAULT_VERTEX, Files.DEFAULT_FRAGMENT)); diff --git a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag index 49c5b1563..47e0808fd 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag @@ -9,6 +9,9 @@ vec4 flw_crumblingSampleColor; void flw_beginFragment() { flw_crumblingSampleColor = texture(flw_crumblingTex, _flw_crumblingTexCoord); + // Make the crumbling overlay transparent when the diffuse layer is transparent. + flw_crumblingSampleColor.a *= flw_fragColor.a; + if (flw_crumblingSampleColor.a < 0.01) { discard; } diff --git a/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.frag b/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.frag index ea7df1078..93a4a0bfa 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.frag +++ b/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.frag @@ -18,9 +18,8 @@ out vec4 fragColor; void main() { _flw_materialFragmentID = _flw_material.x; - _flw_fogID = _flw_material.y & 0xFFFFu; - _flw_cutoutID = _flw_material.y >> 16u; + _flw_unpackUint2x16(_flw_material.y, _flw_cutoutID, _flw_fogID); _flw_unpackMaterial(_flw_material.z, flw_material); flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord); diff --git a/src/main/resources/assets/flywheel/flywheel/internal/instancing/draw.frag b/src/main/resources/assets/flywheel/flywheel/internal/instancing/draw.frag index 35d664298..6e591f2af 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/instancing/draw.frag +++ b/src/main/resources/assets/flywheel/flywheel/internal/instancing/draw.frag @@ -18,9 +18,8 @@ out vec4 fragColor; void main() { _flw_materialFragmentID = _flw_material_instancing.y; - _flw_fogID = _flw_material_instancing.z & 0xFFFFu; - _flw_cutoutID = _flw_material_instancing.z >> 16u; + _flw_unpackUint2x16(_flw_material_instancing.z, _flw_cutoutID, _flw_fogID); _flw_unpackMaterial(_flw_material_instancing.w, flw_material); flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord); diff --git a/src/main/resources/assets/flywheel/flywheel/internal/material.glsl b/src/main/resources/assets/flywheel/flywheel/internal/material.glsl index b60835cd0..423dff5b4 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/material.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/material.glsl @@ -23,3 +23,8 @@ void _flw_unpackMaterial(uint m, out FlwMaterial o) { o.writeMask = (m & WRITE_MASK_MASK) >> 6; o.transparency = (m & TRANSPARENCY_MASK) >> 8; } + +void _flw_unpackUint2x16(uint s, out uint hi, out uint lo) { + hi = (s >> 16) & 0xFFFFu; + lo = s & 0xFFFFu; +}