From 54f34066b55a657f3408703edd3c7a9e6733ca12 Mon Sep 17 00:00:00 2001 From: MCRcortex <18544518+MCRcortex@users.noreply.github.com> Date: Wed, 14 Aug 2024 02:38:11 +1000 Subject: [PATCH] Fix z-fighting with fluids against some special blocks (#2649) Closes #2606 --- .../pipeline/DefaultFluidRenderer.java | 31 ++++++++++++------- .../fabric/render/FluidRendererImpl.java | 9 ++++-- .../neoforge/render/FluidRendererImpl.java | 9 ++++-- 3 files changed, 32 insertions(+), 17 deletions(-) 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..f7b7d484ec 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 @@ -28,6 +28,7 @@ import net.minecraft.tags.FluidTags; import net.minecraft.util.Mth; import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.block.SupportType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; @@ -65,13 +66,21 @@ public DefaultFluidRenderer(ColorProviderRegistry colorProviderRegistry, LightPi this.colorProviderRegistry = colorProviderRegistry; } - private boolean isFluidOccluded(BlockAndTintGetter world, int x, int y, int z, Direction dir, Fluid fluid) { + private boolean isFluidOccluded(BlockAndTintGetter world, int x, int y, int z, Direction dir, BlockState blockState, Fluid fluid) { + //Test own block state first, this prevents waterlogged blocks from having hidden internal geometry + // which can result in z-fighting + var pos = this.scratchPos.set(x, y, z); + if (blockState.canOcclude() && blockState.isFaceSturdy(world, pos, dir, SupportType.FULL)) { + return true; + } + + //Test neighboring block state var adjPos = this.scratchPos.set(x + dir.getStepX(), y + dir.getStepY(), z + dir.getStepZ()); - BlockState blockState = world.getBlockState(adjPos); - if (blockState.getFluidState().getType().isSame(fluid)) { + BlockState adjBlockState = world.getBlockState(adjPos); + if (adjBlockState.getFluidState().getType().isSame(fluid)) { return true; } - return blockState.canOcclude() && dir != Direction.UP && blockState.isFaceSturdy(world, adjPos, dir.getOpposite(), SupportType.FULL); + return adjBlockState.canOcclude() && dir != Direction.UP && adjBlockState.isFaceSturdy(world, adjPos, dir.getOpposite(), SupportType.FULL); } private boolean isSideExposed(BlockAndTintGetter world, int x, int y, int z, Direction dir, float height) { @@ -94,20 +103,20 @@ private boolean isSideExposed(BlockAndTintGetter world, int x, int y, int z, Dir return true; } - public void render(LevelSlice level, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, ColorProvider colorProvider, TextureAtlasSprite[] sprites) { + public void render(LevelSlice level, BlockState blockState, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, ColorProvider colorProvider, TextureAtlasSprite[] sprites) { int posX = blockPos.getX(); int posY = blockPos.getY(); int posZ = blockPos.getZ(); Fluid fluid = fluidState.getType(); - boolean sfUp = this.isFluidOccluded(level, posX, posY, posZ, Direction.UP, fluid); - boolean sfDown = this.isFluidOccluded(level, posX, posY, posZ, Direction.DOWN, fluid) || + boolean sfUp = this.isFluidOccluded(level, posX, posY, posZ, Direction.UP, blockState, fluid); + boolean sfDown = this.isFluidOccluded(level, posX, posY, posZ, Direction.DOWN, blockState, fluid) || !this.isSideExposed(level, posX, posY, posZ, Direction.DOWN, 0.8888889F); - boolean sfNorth = this.isFluidOccluded(level, posX, posY, posZ, Direction.NORTH, fluid); - boolean sfSouth = this.isFluidOccluded(level, posX, posY, posZ, Direction.SOUTH, fluid); - boolean sfWest = this.isFluidOccluded(level, posX, posY, posZ, Direction.WEST, fluid); - boolean sfEast = this.isFluidOccluded(level, posX, posY, posZ, Direction.EAST, fluid); + boolean sfNorth = this.isFluidOccluded(level, posX, posY, posZ, Direction.NORTH, blockState, fluid); + boolean sfSouth = this.isFluidOccluded(level, posX, posY, posZ, Direction.SOUTH, blockState, fluid); + boolean sfWest = this.isFluidOccluded(level, posX, posY, posZ, Direction.WEST, blockState, fluid); + boolean sfEast = this.isFluidOccluded(level, posX, posY, posZ, Direction.EAST, blockState, fluid); if (sfUp && sfDown && sfEast && sfWest && sfNorth && sfSouth) { return; 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..044a500add 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 @@ -69,7 +69,7 @@ public void render(LevelSlice level, BlockState blockState, FluidState fluidStat // To allow invoking this method from the injector, where there is no local Sodium context, the renderer and // parameters are bundled into a DefaultRenderContext which is stored in a ThreadLocal. - defaultContext.setUp(this.colorProviderRegistry, this.defaultRenderer, level, fluidState, blockPos, offset, collector, meshBuilder, material, handler, hasModOverride); + defaultContext.setUp(this.colorProviderRegistry, this.defaultRenderer, level, blockState, fluidState, blockPos, offset, collector, meshBuilder, material, handler, hasModOverride); try { FluidRendering.render(handler, level, blockPos, meshBuilder.asFallbackVertexConsumer(material, collector), blockState, fluidState, defaultContext); @@ -81,6 +81,7 @@ public void render(LevelSlice level, BlockState blockState, FluidState fluidStat private static class DefaultRenderContext implements FluidRendering.DefaultRenderer { private DefaultFluidRenderer renderer; private LevelSlice level; + private BlockState blockState; private FluidState fluidState; private BlockPos blockPos; private BlockPos offset; @@ -91,10 +92,11 @@ private static class DefaultRenderContext implements FluidRendering.DefaultRende private ColorProviderRegistry colorProviderRegistry; private boolean hasModOverride; - public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRenderer renderer, LevelSlice level, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, FluidRenderHandler handler, boolean hasModOverride) { + public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRenderer renderer, LevelSlice level, BlockState blockState, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, FluidRenderHandler handler, boolean hasModOverride) { this.colorProviderRegistry = colorProviderRegistry; this.renderer = renderer; this.level = level; + this.blockState = blockState; this.fluidState = fluidState; this.blockPos = blockPos; this.offset = offset; @@ -108,6 +110,7 @@ public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRende public void clear() { this.renderer = null; this.level = null; + this.blockState = null; this.fluidState = null; this.blockPos = null; this.offset = null; @@ -130,7 +133,7 @@ public ColorProvider getColorProvider(Fluid fluid) { @Override public void render(FluidRenderHandler handler, BlockAndTintGetter world, BlockPos pos, VertexConsumer vertexConsumer, BlockState blockState, FluidState fluidState) { - this.renderer.render(this.level, this.fluidState, this.blockPos, this.offset, this.collector, this.meshBuilder, this.material, + this.renderer.render(this.level, this.blockState, this.fluidState, this.blockPos, this.offset, this.collector, this.meshBuilder, this.material, getColorProvider(fluidState.getType()), handler.getFluidSprites(this.level, this.blockPos, this.fluidState)); } } 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..a844974f6b 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 @@ -59,7 +59,7 @@ public void render(LevelSlice level, BlockState blockState, FluidState fluidStat // parameters are bundled into a DefaultRenderContext which is stored in a ThreadLocal. DefaultRenderContext defaultContext = CURRENT_DEFAULT_CONTEXT.get(); - defaultContext.setUp(this.colorProviderRegistry, this.defaultRenderer, level, fluidState, blockPos, offset, collector, meshBuilder, material, handler); + defaultContext.setUp(this.colorProviderRegistry, this.defaultRenderer, level, blockState, fluidState, blockPos, offset, collector, meshBuilder, material, handler); try { if (!handler.renderFluid(fluidState, level, blockPos, meshBuilder.asFallbackVertexConsumer(material, collector), blockState)) { @@ -73,6 +73,7 @@ public void render(LevelSlice level, BlockState blockState, FluidState fluidStat private static class DefaultRenderContext { private DefaultFluidRenderer renderer; private LevelSlice level; + private BlockState blockState; private FluidState fluidState; private BlockPos blockPos; private BlockPos offset; @@ -82,10 +83,11 @@ private static class DefaultRenderContext { private IClientFluidTypeExtensions handler; private ColorProviderRegistry colorProviderRegistry; - public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRenderer renderer, LevelSlice level, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, IClientFluidTypeExtensions handler) { + public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRenderer renderer, LevelSlice level, BlockState blockState, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, IClientFluidTypeExtensions handler) { this.colorProviderRegistry = colorProviderRegistry; this.renderer = renderer; this.level = level; + this.blockState = blockState; this.fluidState = fluidState; this.blockPos = blockPos; this.offset = offset; @@ -98,6 +100,7 @@ public void setUp(ColorProviderRegistry colorProviderRegistry, DefaultFluidRende public void clear() { this.renderer = null; this.level = null; + this.blockState = null; this.fluidState = null; this.blockPos = null; this.offset = null; @@ -118,7 +121,7 @@ public ColorProvider getColorProvider(Fluid fluid) { } public void render() { - this.renderer.render(this.level, this.fluidState, this.blockPos, this.offset, this.collector, this.meshBuilder, this.material, + this.renderer.render(this.level, this.blockState, this.fluidState, this.blockPos, this.offset, this.collector, this.meshBuilder, this.material, getColorProvider(fluidState.getType()), FluidSpriteCache.getFluidSprites(level, blockPos, fluidState)); } }