Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ private boolean isFluidSelfVisible(BlockState selfBlockState, Direction facing,
// only a non-empty self-shape can occlude anything
if (!ShapeComparisonCache.isEmptyShape(selfShape)) {
// a full self-shape occludes everything
if (ShapeComparisonCache.isFullShape(selfShape) && ShapeComparisonCache.isFullShape(fluidShape)) {
return false;
if (ShapeComparisonCache.isFullShape(selfShape)) {
return !ShapeComparisonCache.isFullShape(fluidShape);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason for this change? I think this changes the behavior.

@Auth0x78 Auth0x78 Jun 26, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason for this was even when the ShapeComparisonCache.isFullShape(fluidShape) returned FALSE, we fall through to the line return this.occlusionCache.get().lookup(fluidShape, selfShape)

We check in occlusion cache, but the issue is that during first render, the cache is empty (no block data as 1st render), so the lookup() in cache create a new entry and the default creation value is FALSE.
Hence the function returns false and the UP face of the fluid is not visible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we simplify this logic to simply return false when ShapeComparisonCache.isFullShape(selfShape)? The check for ShapeComparisonCache.isFullShape(fluidShape) seems redundant to me when the full self shape already culls everything.

@Auth0x78 Auth0x78 Jun 28, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to keep it as in the case of the issue that this resolves there might be the case that the where ShapeComparisonCache.isFullShape(selfShape) returns true, but as the sides of the selfBlock are transparent we need to render the UP face. So in that aspect we need to keep the ShapeComparisonCache.isFullShape(fluidShape) there.

@Auth0x78 Auth0x78 Jun 28, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either we check the isFullShape(fluidShape) or other way is we can check each side wall of the block and see if its full shape or not, but it will require us to loop over North, South, East and West facing wall surfaces of the current block, which might be less optimal than the current approach although a bit more accurate.

Sorry for the delayed response.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The culling shape of a block should match what the actual model represents. If the model says it's full, then we should be allowed to rely on that fact to cull anything within it as determined by the culling shape.

@Auth0x78 Auth0x78 Jun 28, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But here var selfShape = selfBlockState.getFaceOcclusionShape(facing); as we can see that the selfShape is a VoxelShape of the surface in the direction of facing and not the entire block's VoxelShape.

}

// perform occlusion of the fluid by the block it's contained in
Expand All @@ -168,7 +168,12 @@ private boolean isFluidSelfVisible(BlockState selfBlockState, Direction facing,
return true;
}

private boolean isFullBlockFluidSelfVisible(BlockState blockState, Direction dir, VoxelShape fluidShape) {
return this.isFluidSelfVisible(blockState, dir, fluidShape);
}

private boolean isFullBlockFluidSelfVisible(BlockState blockState, Direction dir) {
// Assume that is the fluid block is a full sized block
return this.isFluidSelfVisible(blockState, dir, Shapes.block());
}

Expand Down Expand Up @@ -232,7 +237,8 @@ private boolean isSideExposedOffset(BlockAndTintGetter world, BlockState ownBloc
* Calculates the combined visibility of a fluid face based on the neighboring block states and the fluid state.
*/
private boolean isFullBlockFluidVisible(BlockAndTintGetter world, BlockPos pos, Direction dir, BlockState blockState, FluidState fluid) {
return this.isFullBlockFluidSelfVisible(blockState, dir) && this.isFullBlockFluidSideVisible(world, pos, dir, fluid);
VoxelShape fluidShape = fluid.getShape(world, pos);
return isFullBlockFluidSelfVisible(blockState, dir, fluidShape) && this.isFullBlockFluidSideVisible(world, pos, dir, fluid);
}

/**
Expand Down