From c74b79432afba44449c485d201731c90afc3df45 Mon Sep 17 00:00:00 2001 From: Altirix <19439141+Altirix@users.noreply.github.com> Date: Sat, 11 Sep 2021 00:34:38 +0100 Subject: [PATCH 1/4] fix #858 #859 --- .../client/render/occlusion/BlockOcclusionCache.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java index d69221876c..fc813cb9dd 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java @@ -2,6 +2,7 @@ import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; import net.minecraft.block.BlockState; +import net.minecraft.block.SideShapeType; import net.minecraft.util.function.BooleanBiFunction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -43,9 +44,14 @@ public boolean shouldDrawSide(BlockState selfState, BlockView view, BlockPos pos if (selfShape == VoxelShapes.fullCube() && adjShape == VoxelShapes.fullCube()) { return false; } - + if (selfShape.isEmpty()) { - return true; + if (adjShape.isEmpty()){ + return true; + } + else if (!adjState.isSideSolid(view,pos,facing.getOpposite(), SideShapeType.FULL)){ + return true; + } } return this.calculate(selfShape, adjShape); From e2320f070d3f3dfeccc9921a7b6da235f3e00559 Mon Sep 17 00:00:00 2001 From: Altirix <19439141+Altirix@users.noreply.github.com> Date: Sat, 11 Sep 2021 06:05:46 +0100 Subject: [PATCH 2/4] few comments & enhancement #89 --- .../render/occlusion/BlockOcclusionCache.java | 6 ++-- .../client/render/pipeline/FluidRenderer.java | 29 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java index fc813cb9dd..1090dd70c2 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java @@ -44,13 +44,13 @@ public boolean shouldDrawSide(BlockState selfState, BlockView view, BlockPos pos if (selfShape == VoxelShapes.fullCube() && adjShape == VoxelShapes.fullCube()) { return false; } - + if (selfShape.isEmpty()) { if (adjShape.isEmpty()){ - return true; + return true; // face of potted plants with cull face enabled are rendered if top slab is placed above } else if (!adjState.isSideSolid(view,pos,facing.getOpposite(), SideShapeType.FULL)){ - return true; + return true; // face of potted plants rendered if top stair placed above } } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java index 631a36cf11..26d6dc5665 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java @@ -19,10 +19,7 @@ import me.jellysquid.mods.sodium.common.util.DirectionUtil; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.impl.client.rendering.fluid.FluidRenderHandlerRegistryImpl; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.StainedGlassBlock; +import net.minecraft.block.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.texture.Sprite; @@ -72,17 +69,23 @@ public FluidRenderer(LightPipelineProvider lighters, BiomeColorBlender biomeColo } private boolean isFluidExposed(BlockRenderView world, int x, int y, int z, Direction dir, Fluid fluid) { - // Up direction is hard to test since it doesnt fill the block - if(dir != Direction.UP) { - BlockPos pos = this.scratchPos.set(x, y, z); - BlockState blockState = world.getBlockState(pos); + BlockPos pos = this.scratchPos.set(x, y, z); + BlockState blockState = world.getBlockState(pos); + + if (dir == Direction.UP){ + if (blockState.isSideSolid(world,pos,dir, SideShapeType.FULL)){ + return false; // Fluid is in waterlogged stair or slab that self occludes + } + } + + else{ VoxelShape shape = blockState.getCullingShape(world, pos); if (blockState.isOpaque() && VoxelShapes.isSideCovered(VoxelShapes.fullCube(), shape, dir.getOpposite())) { - return false; // Fluid is in waterlogged block that self occludes + return false; // Fluid is in waterlogged full block that self occludes } } - BlockPos pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); + pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); return !world.getFluidState(pos).getFluid().matchesType(fluid); } @@ -90,9 +93,15 @@ private boolean isSideExposed(BlockRenderView world, int x, int y, int z, Direct BlockPos pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); BlockState blockState = world.getBlockState(pos); + if (blockState.getBlock() instanceof SlabBlock){ + if (dir == Direction.UP){ + return false; + }} + if (blockState.isOpaque()) { VoxelShape shape = blockState.getCullingShape(world, pos); + // Hoist these checks to avoid allocating the shape below if (shape == VoxelShapes.fullCube()) { // The top face always be inset, so if the shape above is a full cube it can't possibly occlude From b92a869f4805ce452d8ac90af02a71959db25860 Mon Sep 17 00:00:00 2001 From: Altirix <19439141+Altirix@users.noreply.github.com> Date: Sat, 11 Sep 2021 07:19:23 +0100 Subject: [PATCH 3/4] changes to comments, affects more than just potted plants Fences, Walls, Carpets, Powdered snow, probs loads im missing --- .../sodium/client/render/occlusion/BlockOcclusionCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java index 1090dd70c2..73640bd05f 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/occlusion/BlockOcclusionCache.java @@ -47,10 +47,10 @@ public boolean shouldDrawSide(BlockState selfState, BlockView view, BlockPos pos if (selfShape.isEmpty()) { if (adjShape.isEmpty()){ - return true; // face of potted plants with cull face enabled are rendered if top slab is placed above + return true; //example: top face of potted plants if top slab is placed above } else if (!adjState.isSideSolid(view,pos,facing.getOpposite(), SideShapeType.FULL)){ - return true; // face of potted plants rendered if top stair placed above + return true; //example: face of potted plants rendered if top stair placed above } } From c83305178831238b86d30a0735e128de89fb5ace Mon Sep 17 00:00:00 2001 From: Altirix <19439141+Altirix@users.noreply.github.com> Date: Sat, 11 Sep 2021 07:51:57 +0100 Subject: [PATCH 4/4] FluidRenderer changes IsFluidExposed -> IsFluidOccluded IsSideSolid is used to determine if a side would hide the water texture, should be disabled as this can cause Z fighting when further away --- .../client/render/pipeline/FluidRenderer.java | 70 ++++++++----------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java index 26d6dc5665..6a97494af6 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/pipeline/FluidRenderer.java @@ -5,13 +5,13 @@ import me.jellysquid.mods.sodium.client.model.light.LightPipelineProvider; import me.jellysquid.mods.sodium.client.model.light.data.QuadLightData; import me.jellysquid.mods.sodium.client.model.quad.ModelQuad; +import me.jellysquid.mods.sodium.client.model.quad.ModelQuadColorProvider; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable; import me.jellysquid.mods.sodium.client.model.quad.blender.BiomeColorBlender; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadWinding; -import me.jellysquid.mods.sodium.client.model.quad.ModelQuadColorProvider; import me.jellysquid.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink; import me.jellysquid.mods.sodium.client.util.Norm3b; @@ -19,7 +19,8 @@ import me.jellysquid.mods.sodium.common.util.DirectionUtil; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.impl.client.rendering.fluid.FluidRenderHandlerRegistryImpl; -import net.minecraft.block.*; +import net.minecraft.block.BlockState; +import net.minecraft.block.SideShapeType; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.texture.Sprite; @@ -68,40 +69,25 @@ public FluidRenderer(LightPipelineProvider lighters, BiomeColorBlender biomeColo this.biomeColorBlender = biomeColorBlender; } - private boolean isFluidExposed(BlockRenderView world, int x, int y, int z, Direction dir, Fluid fluid) { + private boolean isFluidOccluded(BlockRenderView world, int x, int y, int z, Direction dir, Fluid fluid) { BlockPos pos = this.scratchPos.set(x, y, z); BlockState blockState = world.getBlockState(pos); + BlockPos adjPos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); - if (dir == Direction.UP){ - if (blockState.isSideSolid(world,pos,dir, SideShapeType.FULL)){ - return false; // Fluid is in waterlogged stair or slab that self occludes - } - } - - else{ - VoxelShape shape = blockState.getCullingShape(world, pos); - if (blockState.isOpaque() && VoxelShapes.isSideCovered(VoxelShapes.fullCube(), shape, dir.getOpposite())) { - return false; // Fluid is in waterlogged full block that self occludes + if (blockState.isOpaque()) { + return world.getFluidState(adjPos).getFluid().matchesType(fluid) || blockState.isSideSolid(world,pos,dir, SideShapeType.FULL); + // fluidlogged or next to water, occlude sides that are solid or the same liquid } - } - - pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); - return !world.getFluidState(pos).getFluid().matchesType(fluid); + return world.getFluidState(adjPos).getFluid().matchesType(fluid); } private boolean isSideExposed(BlockRenderView world, int x, int y, int z, Direction dir, float height) { BlockPos pos = this.scratchPos.set(x + dir.getOffsetX(), y + dir.getOffsetY(), z + dir.getOffsetZ()); BlockState blockState = world.getBlockState(pos); - if (blockState.getBlock() instanceof SlabBlock){ - if (dir == Direction.UP){ - return false; - }} - if (blockState.isOpaque()) { VoxelShape shape = blockState.getCullingShape(world, pos); - // Hoist these checks to avoid allocating the shape below if (shape == VoxelShapes.fullCube()) { // The top face always be inset, so if the shape above is a full cube it can't possibly occlude @@ -125,15 +111,15 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos Fluid fluid = fluidState.getFluid(); - boolean sfUp = this.isFluidExposed(world, posX, posY, posZ, Direction.UP, fluid); - boolean sfDown = this.isFluidExposed(world, posX, posY, posZ, Direction.DOWN, fluid) && - this.isSideExposed(world, posX, posY, posZ, Direction.DOWN, 0.8888889F); - boolean sfNorth = this.isFluidExposed(world, posX, posY, posZ, Direction.NORTH, fluid); - boolean sfSouth = this.isFluidExposed(world, posX, posY, posZ, Direction.SOUTH, fluid); - boolean sfWest = this.isFluidExposed(world, posX, posY, posZ, Direction.WEST, fluid); - boolean sfEast = this.isFluidExposed(world, posX, posY, posZ, Direction.EAST, fluid); + boolean sfUp = this.isFluidOccluded(world, posX, posY, posZ, Direction.UP, fluid); + boolean sfDown = this.isFluidOccluded(world, posX, posY, posZ, Direction.DOWN, fluid) || + !this.isSideExposed(world, posX, posY, posZ, Direction.DOWN, 0.8888889F); + boolean sfNorth = this.isFluidOccluded(world, posX, posY, posZ, Direction.NORTH, fluid); + boolean sfSouth = this.isFluidOccluded(world, posX, posY, posZ, Direction.SOUTH, fluid); + boolean sfWest = this.isFluidOccluded(world, posX, posY, posZ, Direction.WEST, fluid); + boolean sfEast = this.isFluidOccluded(world, posX, posY, posZ, Direction.EAST, fluid); - if (!sfUp && !sfDown && !sfEast && !sfWest && !sfNorth && !sfSouth) { + if (sfUp && sfDown && sfEast && sfWest && sfNorth && sfSouth) { return false; } @@ -151,7 +137,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos float h3 = this.getCornerHeight(world, posX + 1, posY, posZ + 1, fluidState.getFluid()); float h4 = this.getCornerHeight(world, posX + 1, posY, posZ, fluidState.getFluid()); - float yOffset = sfDown ? EPSILON : 0.0F; + float yOffset = sfDown ? 0.0F : EPSILON; final ModelQuadViewMutable quad = this.quad; @@ -160,7 +146,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos quad.setFlags(0); - if (sfUp && this.isSideExposed(world, posX, posY, posZ, Direction.UP, Math.min(Math.min(h1, h2), Math.min(h3, h4)))) { + if (!sfUp && this.isSideExposed(world, posX, posY, posZ, Direction.UP, Math.min(Math.min(h1, h2), Math.min(h3, h4)))) { h1 -= EPSILON; h2 -= EPSILON; h3 -= EPSILON; @@ -237,7 +223,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos rendered = true; } - if (sfDown) { + if (!sfDown) { Sprite sprite = sprites[0]; float minU = sprite.getMinU(); @@ -273,7 +259,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos switch (dir) { case NORTH: - if (!sfNorth) { + if (sfNorth) { continue; } @@ -285,7 +271,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos z2 = z1; break; case SOUTH: - if (!sfSouth) { + if (sfSouth) { continue; } @@ -297,7 +283,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos z2 = z1; break; case WEST: - if (!sfWest) { + if (sfWest) { continue; } @@ -309,7 +295,7 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos z2 = 0.0f; break; case EAST: - if (!sfEast) { + if (sfEast) { continue; } @@ -332,11 +318,13 @@ public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos Sprite sprite = sprites[1]; if (isWater) { - BlockPos posAdj = this.scratchPos.set(adjX, adjY, adjZ); - Block block = world.getBlockState(posAdj).getBlock(); + BlockPos adjPos = this.scratchPos.set(adjX, adjY, adjZ); + BlockState adjBlock = world.getBlockState(adjPos); - if (block == Blocks.GLASS || block instanceof StainedGlassBlock) { + if (!adjBlock.isOpaque() && !adjBlock.isAir()) { + // ice, glass, stained glass, tinted glass sprite = this.waterOverlaySprite; + } }