From a86df1d9504662f57dc9ba1265c691bc53b59540 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 14 Aug 2024 20:33:16 -0700 Subject: [PATCH] Add support for vertex alphas --- .../model/color/ColorProviderRegistry.java | 5 ++-- .../model/color/DefaultColorProviders.java | 6 ++-- .../quad/blender/BlendedColorProvider.java | 14 +++++----- .../compile/buffers/ChunkVertexConsumer.java | 7 +++-- .../chunk/compile/pipeline/BlockRenderer.java | 9 ++---- .../pipeline/DefaultFluidRenderer.java | 5 +++- .../vertex/format/ChunkVertexEncoder.java | 1 + .../format/impl/CompactChunkVertex.java | 3 +- .../render/NonTerrainBlockRenderContext.java | 2 +- .../client/services/FluidRendererFactory.java | 7 +++++ .../shaders/blocks/block_layer_opaque.fsh | 9 ++---- .../fabric/render/FluidRendererImpl.java | 22 +++++++++++++++ .../neoforge/render/FluidRendererImpl.java | 28 +++++++++++++++++++ 13 files changed, 88 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/ColorProviderRegistry.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/ColorProviderRegistry.java index efc349e062..1d611d691e 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/ColorProviderRegistry.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/ColorProviderRegistry.java @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import it.unimi.dsi.fastutil.objects.ReferenceSet; import net.caffeinemc.mods.sodium.client.model.color.interop.BlockColorsExtension; +import net.caffeinemc.mods.sodium.client.services.FluidRendererFactory; import net.minecraft.client.color.block.BlockColors; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -42,10 +43,10 @@ private void installOverrides() { Blocks.OAK_LEAVES, Blocks.JUNGLE_LEAVES, Blocks.ACACIA_LEAVES, Blocks.DARK_OAK_LEAVES, Blocks.VINE, Blocks.MANGROVE_LEAVES); - this.registerBlocks(DefaultColorProviders.WaterColorProvider.BLOCKS, + this.registerBlocks(FluidRendererFactory.getInstance().getWaterBlockColorProvider(), Blocks.WATER, Blocks.BUBBLE_COLUMN); - this.registerFluids(DefaultColorProviders.WaterColorProvider.FLUIDS, + this.registerFluids(FluidRendererFactory.getInstance().getWaterColorProvider(), Fluids.WATER, Fluids.FLOWING_WATER); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/DefaultColorProviders.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/DefaultColorProviders.java index 542a2ed429..e02fdc2734 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/DefaultColorProviders.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/color/DefaultColorProviders.java @@ -23,7 +23,7 @@ private GrassColorProvider() { } @Override - protected int getColor(LevelSlice slice, BlockPos pos) { + protected int getColor(LevelSlice slice, T state, BlockPos pos) { return BiomeColors.getAverageGrassColor(slice, pos); } } @@ -36,7 +36,7 @@ private FoliageColorProvider() { } @Override - protected int getColor(LevelSlice slice, BlockPos pos) { + protected int getColor(LevelSlice slice, T state, BlockPos pos) { return BiomeColors.getAverageFoliageColor(slice, pos); } } @@ -50,7 +50,7 @@ private WaterColorProvider() { } @Override - protected int getColor(LevelSlice slice, BlockPos pos) { + protected int getColor(LevelSlice slice, T state, BlockPos pos) { return BiomeColors.getAverageWaterColor(slice, pos); } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/quad/blender/BlendedColorProvider.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/quad/blender/BlendedColorProvider.java index 1f68c14b07..b1d53d164a 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/quad/blender/BlendedColorProvider.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/quad/blender/BlendedColorProvider.java @@ -12,11 +12,11 @@ public abstract class BlendedColorProvider implements ColorProvider { @Override public void getColors(LevelSlice slice, BlockPos pos, BlockPos.MutableBlockPos scratchPos, T state, ModelQuadView quad, int[] output) { for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++) { - output[vertexIndex] = this.getVertexColor(slice, pos, scratchPos, quad, vertexIndex); + output[vertexIndex] = this.getVertexColor(slice, pos, scratchPos, quad, state, vertexIndex); } } - private int getVertexColor(LevelSlice slice, BlockPos pos, BlockPos.MutableBlockPos scratchPos, ModelQuadView quad, int vertexIndex) { + private int getVertexColor(LevelSlice slice, BlockPos pos, BlockPos.MutableBlockPos scratchPos, ModelQuadView quad, T state, int vertexIndex) { // Offset the position by -0.5f to align smooth blending with flat blending. final float posX = quad.getX(vertexIndex) - 0.5f; final float posY = quad.getY(vertexIndex) - 0.5f; @@ -35,10 +35,10 @@ private int getVertexColor(LevelSlice slice, BlockPos pos, BlockPos.MutableBlock final int blockIntZ = pos.getZ() + posIntZ; // Retrieve the color values for each neighboring block - final int c00 = this.getColor(slice, scratchPos.set(blockIntX + 0, blockIntY, blockIntZ + 0)); - final int c01 = this.getColor(slice, scratchPos.set(blockIntX + 0, blockIntY, blockIntZ + 1)); - final int c10 = this.getColor(slice, scratchPos.set(blockIntX + 1, blockIntY, blockIntZ + 0)); - final int c11 = this.getColor(slice, scratchPos.set(blockIntX + 1, blockIntY, blockIntZ + 1)); + final int c00 = this.getColor(slice, state, scratchPos.set(blockIntX + 0, blockIntY, blockIntZ + 0)); + final int c01 = this.getColor(slice, state, scratchPos.set(blockIntX + 0, blockIntY, blockIntZ + 1)); + final int c10 = this.getColor(slice, state, scratchPos.set(blockIntX + 1, blockIntY, blockIntZ + 0)); + final int c11 = this.getColor(slice, state, scratchPos.set(blockIntX + 1, blockIntY, blockIntZ + 1)); // Linear interpolation across the Z-axis int z0; @@ -69,5 +69,5 @@ private int getVertexColor(LevelSlice slice, BlockPos pos, BlockPos.MutableBlock return x0; } - protected abstract int getColor(LevelSlice slice, BlockPos pos); + protected abstract int getColor(LevelSlice slice, T state, BlockPos pos); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java index e5d449f8c4..48ec0c9a3e 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkVertexConsumer.java @@ -43,6 +43,7 @@ public void setData(Material material, TranslucentGeometryCollector collector) { vertex.x = x; vertex.y = y; vertex.z = z; + vertex.ao = 1.0f; this.writtenAttributes |= ATTRIBUTE_POSITION_BIT; return potentiallyEndVertex(); } @@ -51,7 +52,7 @@ public void setData(Material material, TranslucentGeometryCollector collector) { @Override public @NotNull VertexConsumer setColor(int red, int green, int blue, int alpha) { ChunkVertexEncoder.Vertex vertex = this.vertices[this.vertexIndex]; - vertex.color = ColorABGR.pack(red, green, blue, 0xFF); + vertex.color = ColorABGR.pack(red, green, blue, alpha); this.writtenAttributes |= ATTRIBUTE_COLOR_BIT; return potentiallyEndVertex(); } @@ -59,7 +60,7 @@ public void setData(Material material, TranslucentGeometryCollector collector) { @Override public @NotNull VertexConsumer setColor(float red, float green, float blue, float alpha) { ChunkVertexEncoder.Vertex vertex = this.vertices[this.vertexIndex]; - vertex.color = ColorABGR.pack(red, green, blue, 1); + vertex.color = ColorABGR.pack(red, green, blue, alpha); this.writtenAttributes |= ATTRIBUTE_COLOR_BIT; return potentiallyEndVertex(); } @@ -67,7 +68,7 @@ public void setData(Material material, TranslucentGeometryCollector collector) { @Override public @NotNull VertexConsumer setColor(int argb) { ChunkVertexEncoder.Vertex vertex = this.vertices[this.vertexIndex]; - vertex.color = ColorARGB.toABGR(argb, 0xFF); + vertex.color = ColorARGB.toABGR(argb); this.writtenAttributes |= ATTRIBUTE_COLOR_BIT; return potentiallyEndVertex(); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java index df6851a805..93fdcac9f5 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java @@ -144,9 +144,7 @@ private void colorizeQuad(MutableQuadViewImpl quad, int colorIndex) { colorProvider.getColors(this.slice, this.pos, this.scratchPos, this.state, quad, vertexColors); for (int i = 0; i < 4; i++) { - // Set alpha to 0xFF in case a quad transform inspects the color. - // We do not support per-vertex alpha, however, so this will get discarded at vertex encoding time. - quad.color(i, ColorHelper.multiplyColor(0xFF000000 | vertexColors[i], quad.color(i))); + quad.color(i, ColorHelper.multiplyColor(vertexColors[i], quad.color(i))); } } } @@ -166,9 +164,8 @@ private void bufferQuad(MutableQuadViewImpl quad, float[] brightnesses, Material out.z = quad.z(srcIndex) + offset.z; // FRAPI uses ARGB color format; convert to ABGR. - // Due to our vertex format, the alpha from the quad color is ignored entirely. - out.color = ColorARGB.toABGR(quad.color(srcIndex), brightnesses[srcIndex]); - + out.color = ColorARGB.toABGR(quad.color(srcIndex)); + out.ao = brightnesses[srcIndex]; out.u = quad.u(srcIndex); out.v = quad.v(srcIndex); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer.java index 916e6f2a15..aa95c64e0c 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer.java @@ -54,6 +54,7 @@ public class DefaultFluidRenderer { private final QuadLightData quadLightData = new QuadLightData(); private final int[] quadColors = new int[4]; + private final float[] brightness = new float[4]; private final ChunkVertexEncoder.Vertex[] vertices = ChunkVertexEncoder.Vertex.uninitializedQuad(); private final ColorProviderRegistry colorProviderRegistry; @@ -385,7 +386,8 @@ private void updateQuad(ModelQuadViewMutable quad, LevelSlice level, BlockPos po // multiply the per-vertex color against the combined brightness // the combined brightness is the per-vertex brightness multiplied by the block's brightness for (int i = 0; i < 4; i++) { - this.quadColors[i] = ColorARGB.toABGR(this.quadColors[i], light.br[i] * brightness); + this.quadColors[i] = ColorARGB.toABGR(this.quadColors[i]); + this.brightness[i] = light.br[i] * brightness; } } @@ -400,6 +402,7 @@ private void writeQuad(ChunkModelBuilder builder, TranslucentGeometryCollector c out.z = offset.getZ() + quad.getZ(i); out.color = this.quadColors[i]; + out.ao = this.brightness[i]; out.u = quad.getTexU(i); out.v = quad.getTexV(i); out.light = this.quadLightData.lm[i]; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder.java index 3db1859cc0..c0bfb4cff3 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder.java @@ -10,6 +10,7 @@ class Vertex { public float y; public float z; public int color; + public float ao; public float u; public float v; public int light; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java index 67dba7bdad..1220f078e4 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java @@ -5,6 +5,7 @@ import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType; +import net.caffeinemc.mods.sodium.client.render.frapi.helper.ColorHelper; import net.minecraft.util.Mth; import org.lwjgl.system.MemoryUtil; @@ -59,7 +60,7 @@ public ChunkVertexEncoder getEncoder() { MemoryUtil.memPutInt(ptr + 0L, packPositionHi(x, y, z)); MemoryUtil.memPutInt(ptr + 4L, packPositionLo(x, y, z)); - MemoryUtil.memPutInt(ptr + 8L, vertex.color); + MemoryUtil.memPutInt(ptr + 8L, ColorHelper.multiplyRGB(vertex.color, vertex.ao)); MemoryUtil.memPutInt(ptr + 12L, packTexture(u, v)); MemoryUtil.memPutInt(ptr + 16L, packLightAndData(light, material.bits(), section)); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java index 35433471b6..4c78b8c84e 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java @@ -106,7 +106,7 @@ protected void processQuad(MutableQuadViewImpl quad) { private void colorizeQuad(MutableQuadViewImpl quad, int colorIndex) { if (colorIndex != -1) { - final int blockColor = 0xFF000000 | this.colorMap.getColor(this.state, this.level, this.pos, colorIndex); + final int blockColor = this.colorMap.getColor(this.state, this.level, this.pos, colorIndex); for (int i = 0; i < 4; i++) { quad.color(i, ColorHelper.multiplyColor(blockColor, quad.color(i))); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/services/FluidRendererFactory.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/services/FluidRendererFactory.java index 7d089dd507..87562af9ea 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/services/FluidRendererFactory.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/services/FluidRendererFactory.java @@ -2,7 +2,10 @@ import net.caffeinemc.mods.sodium.client.model.color.ColorProviderRegistry; import net.caffeinemc.mods.sodium.client.model.light.LightPipelineProvider; +import net.caffeinemc.mods.sodium.client.model.quad.blender.BlendedColorProvider; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; public interface FluidRendererFactory { FluidRendererFactory INSTANCE = Services.load(FluidRendererFactory.class); @@ -18,4 +21,8 @@ static FluidRendererFactory getInstance() { * @return A new fluid renderer. */ FluidRenderer createPlatformFluidRenderer(ColorProviderRegistry colorRegistry, LightPipelineProvider lightPipelineProvider); + + BlendedColorProvider getWaterColorProvider(); + + BlendedColorProvider getWaterBlockColorProvider(); } diff --git a/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.fsh b/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.fsh index 6bcf30056f..314e696962 100644 --- a/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.fsh +++ b/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.fsh @@ -20,17 +20,14 @@ out vec4 fragColor; // The output fragment for the color framebuffer void main() { vec4 diffuseColor = texture(u_BlockTex, v_TexCoord, v_MaterialMipBias); + // Apply per-vertex color + diffuseColor *= v_Color; + #ifdef USE_FRAGMENT_DISCARD if (diffuseColor.a < v_MaterialAlphaCutoff) { discard; } #endif - // Apply per-vertex color - diffuseColor.rgb *= v_Color.rgb; - - // Apply ambient occlusion "shade" - diffuseColor.rgb *= v_Color.a; - fragColor = _linearFog(diffuseColor, v_FragDistance, u_FogColor, u_FogStart, u_FogEnd); } \ No newline at end of file diff --git a/fabric/src/main/java/net/caffeinemc/mods/sodium/fabric/render/FluidRendererImpl.java b/fabric/src/main/java/net/caffeinemc/mods/sodium/fabric/render/FluidRendererImpl.java index d4ba56c2ab..a1691bc0bd 100644 --- a/fabric/src/main/java/net/caffeinemc/mods/sodium/fabric/render/FluidRendererImpl.java +++ b/fabric/src/main/java/net/caffeinemc/mods/sodium/fabric/render/FluidRendererImpl.java @@ -4,6 +4,7 @@ import net.caffeinemc.mods.sodium.client.model.color.ColorProvider; import net.caffeinemc.mods.sodium.client.model.color.ColorProviderRegistry; import net.caffeinemc.mods.sodium.client.model.light.LightPipelineProvider; +import net.caffeinemc.mods.sodium.client.model.quad.blender.BlendedColorProvider; import net.caffeinemc.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers; import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.DefaultFluidRenderer; @@ -16,6 +17,7 @@ import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRendering; +import net.minecraft.client.renderer.BiomeColors; import net.minecraft.core.BlockPos; import net.minecraft.tags.FluidTags; import net.minecraft.world.level.BlockAndTintGetter; @@ -140,5 +142,25 @@ public static class FabricFactory implements FluidRendererFactory { public FluidRenderer createPlatformFluidRenderer(ColorProviderRegistry colorRegistry, LightPipelineProvider lightPipelineProvider) { return new FluidRendererImpl(colorRegistry, lightPipelineProvider); } + + @Override + public BlendedColorProvider getWaterColorProvider() { + return new BlendedColorProvider<>() { + @Override + protected int getColor(LevelSlice slice, FluidState state, BlockPos pos) { + return BiomeColors.getAverageWaterColor(slice, pos) | 0xFF000000; + } + }; + } + + @Override + public BlendedColorProvider getWaterBlockColorProvider() { + return new BlendedColorProvider<>() { + @Override + protected int getColor(LevelSlice slice, BlockState state, BlockPos pos) { + return BiomeColors.getAverageWaterColor(slice, pos) | 0xFF000000; + } + }; + } } } diff --git a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/render/FluidRendererImpl.java b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/render/FluidRendererImpl.java index e439e1a5d8..c1f89897ec 100644 --- a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/render/FluidRendererImpl.java +++ b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/render/FluidRendererImpl.java @@ -3,6 +3,7 @@ import net.caffeinemc.mods.sodium.client.model.color.ColorProvider; import net.caffeinemc.mods.sodium.client.model.color.ColorProviderRegistry; import net.caffeinemc.mods.sodium.client.model.light.LightPipelineProvider; +import net.caffeinemc.mods.sodium.client.model.quad.blender.BlendedColorProvider; import net.caffeinemc.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers; import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.DefaultFluidRenderer; @@ -16,9 +17,12 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.textures.FluidSpriteCache; +import java.util.Objects; + public class FluidRendererImpl extends FluidRenderer { // The current default context is set up before invoking FluidRenderHandler#renderFluid and cleared afterwards. private static final ThreadLocal CURRENT_DEFAULT_CONTEXT = ThreadLocal.withInitial(DefaultRenderContext::new); @@ -128,5 +132,29 @@ public static class ForgeFactory implements FluidRendererFactory { public FluidRenderer createPlatformFluidRenderer(ColorProviderRegistry colorRegistry, LightPipelineProvider lightPipelineProvider) { return new FluidRendererImpl(colorRegistry, lightPipelineProvider); } + + @Override + public BlendedColorProvider getWaterColorProvider() { + final IClientFluidTypeExtensions ext = IClientFluidTypeExtensions.of(Fluids.WATER); + + return new BlendedColorProvider<>() { + @Override + protected int getColor(LevelSlice slice, FluidState state, BlockPos pos) { + return ext.getTintColor(state, slice, pos); + } + }; + } + + @Override + public BlendedColorProvider getWaterBlockColorProvider() { + final IClientFluidTypeExtensions ext = IClientFluidTypeExtensions.of(Fluids.WATER); + + return new BlendedColorProvider<>() { + @Override + protected int getColor(LevelSlice slice, BlockState state, BlockPos pos) { + return ext.getTintColor(state.getFluidState().isEmpty() ? Fluids.WATER.defaultFluidState() : state.getFluidState(), slice, pos); + } + }; + } } }