diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumBlockRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumBlockRendererMixin.java index 8c8241f12e..b63318fc51 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumBlockRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumBlockRendererMixin.java @@ -6,21 +6,55 @@ package meteordevelopment.meteorclient.mixin.sodium; import meteordevelopment.meteorclient.systems.modules.render.Xray; +import net.caffeinemc.mods.sodium.api.util.ColorABGR; import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderer; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material; +import net.caffeinemc.mods.sodium.client.render.model.MutableQuadViewImpl; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BlockStateModel; import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(value = BlockRenderer.class) -public abstract class SodiumBlockRendererMixin { - @Inject(method = "renderModel", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/model/color/ColorProviderRegistry;getColorProvider(Lnet/minecraft/block/Block;)Lnet/caffeinemc/mods/sodium/client/model/color/ColorProvider;", shift = At.Shift.AFTER), cancellable = true) - private void onRenderModel(BlockStateModel model, BlockState state, BlockPos pos, BlockPos origin, CallbackInfo ci) { - int alpha = Xray.getAlpha(state, pos); +@Mixin(value = BlockRenderer.class, remap = false) +public class SodiumBlockRendererMixin { + @Unique + private int xrayAlpha; - if (alpha == 0) ci.cancel(); + @Inject(method = "renderModel", at = @At("HEAD"), cancellable = true) + private void onRenderModel(BlockStateModel model, BlockState state, BlockPos pos, BlockPos origin, CallbackInfo info) { + xrayAlpha = Xray.getAlpha(state, pos); + + // Cancel block rendering when alpha is 0, required for Iris support but unnecessery to check for shaders, we already force be disabled when Xray is enabled + if (xrayAlpha == 0) { + info.cancel(); + } + } + + @Inject(method = "bufferQuad", at = @At("HEAD")) + private void onBufferQuad(MutableQuadViewImpl quad, float[] brightnesses, Material material, CallbackInfo info) { + if (xrayAlpha != -1) { + for (int i = 0; i < 4; i++) { + int color = quad.baseColor(i); + int r = ColorABGR.unpackRed(color); + int g = ColorABGR.unpackGreen(color); + int b = ColorABGR.unpackBlue(color); + + quad.setColor(i, ColorABGR.pack(r, g, b, xrayAlpha)); + } + } + } + + @ModifyArg(method = "processQuad", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer;bufferQuad(Lnet/caffeinemc/mods/sodium/client/render/model/MutableQuadViewImpl;[FLnet/caffeinemc/mods/sodium/client/render/chunk/terrain/material/Material;)V"), index = 2) + private Material modifyMaterial(Material material) { + if (xrayAlpha != -1) { + return DefaultMaterials.TRANSLUCENT; + } + return material; } } diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumDefaultFluidRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumDefaultFluidRendererMixin.java new file mode 100644 index 0000000000..a1e5ecc453 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumDefaultFluidRendererMixin.java @@ -0,0 +1,65 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.mixin.sodium; + +import meteordevelopment.meteorclient.systems.modules.render.Xray; +import net.caffeinemc.mods.sodium.client.model.color.ColorProvider; +import net.caffeinemc.mods.sodium.client.model.light.LightPipeline; +import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadViewMutable; +import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing; +import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; +import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.DefaultFluidRenderer; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; +import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material; +import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector; +import net.caffeinemc.mods.sodium.client.world.LevelSlice; +import net.minecraft.client.texture.Sprite; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = DefaultFluidRenderer.class, remap = false) +public abstract class SodiumDefaultFluidRendererMixin { + @Shadow + private int[] quadColors; + + @Unique + private int xrayAlpha; + + @Inject(method = "render", at = @At("HEAD"), cancellable = true) + private void onRender(LevelSlice level, net.minecraft.block.BlockState blockState, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, ColorProvider colorProvider, Sprite[] sprites, CallbackInfo ci) { + xrayAlpha = Xray.getAlpha(fluidState.getBlockState(), blockPos); + + // Cancel block rendering when alpha is 0, required for Iris support but unnecessery to check for shaders, we already force be disabled when Xray is enabled + if (xrayAlpha == 0) { + ci.cancel(); + } + } + + @Inject(method = "updateQuad", at = @At("TAIL")) + private void onUpdateQuad(ModelQuadViewMutable quad, LevelSlice level, BlockPos pos, LightPipeline lighter, Direction dir, ModelQuadFacing facing, float brightness, ColorProvider colorProvider, FluidState fluidState, CallbackInfo ci) { + if (xrayAlpha != -1) { + for (int i = 0; i < 4; i++) { + quadColors[i] = (quadColors[i] & 0x00FFFFFF) | (xrayAlpha << 24); + } + } + } + + @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer;writeQuad(Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder;Lnet/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector;Lnet/caffeinemc/mods/sodium/client/render/chunk/terrain/material/Material;Lnet/minecraft/util/math/BlockPos;Lnet/caffeinemc/mods/sodium/client/model/quad/ModelQuadView;Lnet/caffeinemc/mods/sodium/client/model/quad/properties/ModelQuadFacing;Z)V"), index = 2) + private Material modifyMaterial(Material material) { + if (xrayAlpha != -1) { + return DefaultMaterials.TRANSLUCENT; + } + return material; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumInnerPartitionBSPNodeMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumInnerPartitionBSPNodeMixin.java new file mode 100644 index 0000000000..792e26ee49 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/mixin/sodium/SodiumInnerPartitionBSPNodeMixin.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.mixin.sodium; + +import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; +import org.joml.Vector3fc; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(targets = "net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.bsp_tree.InnerPartitionBSPNode", remap = false) +public class SodiumInnerPartitionBSPNodeMixin { + private static final float VERTEX_EPSILON = 0.00001f; + + @Inject(method = "interpolateAttributes(FLorg/joml/Vector3fc;Lnet/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder$Vertex;Lnet/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder$Vertex;Lnet/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder$Vertex;Lnet/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder$Vertex;Lnet/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexEncoder$Vertex;)V", at = @At("HEAD"), cancellable = true) + private static void onInterpolateAttributes(float splitDistance, Vector3fc splitPlane, + ChunkVertexEncoder.Vertex inside, ChunkVertexEncoder.Vertex outside, ChunkVertexEncoder.Vertex targetA, + ChunkVertexEncoder.Vertex targetB, ChunkVertexEncoder.Vertex targetC, CallbackInfo ci) { + float insideToOutsideX = outside.x - inside.x; + float insideToOutsideY = outside.y - inside.y; + float insideToOutsideZ = outside.z - inside.z; + + if (Math.abs(insideToOutsideX) < VERTEX_EPSILON && Math.abs(insideToOutsideY) < VERTEX_EPSILON && Math.abs(insideToOutsideZ) < VERTEX_EPSILON) { + return; + } + + float splitPlaneEdgeDot = splitPlane.dot(insideToOutsideX, insideToOutsideY, insideToOutsideZ); + if (splitPlaneEdgeDot == 0.0F) { + ci.cancel(); + } + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java index be042352c5..c2d5335f86 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java @@ -68,8 +68,8 @@ public void onDeactivate() { @Override public WWidget getWidget(GuiTheme theme) { - if (MixinPlugin.isSodiumPresent) return theme.label("Warning: Due to Sodium in use, opacity is overridden to 0."); - if (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse()) return theme.label("Warning: Due to shaders in use, opacity is overridden to 0."); + if (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse()) + return theme.label("Warning: Due to shaders in use, opacity is overridden to 0."); return null; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java index 351a230172..efb0bb40b8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java @@ -80,7 +80,6 @@ public void onDeactivate() { @Override public WWidget getWidget(GuiTheme theme) { - if (MixinPlugin.isSodiumPresent) return theme.label("Warning: Due to Sodium in use, opacity is overridden to 0."); if (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse()) return theme.label("Warning: Due to shaders in use, opacity is overridden to 0."); return null; @@ -120,7 +119,7 @@ public static int getAlpha(BlockState state, BlockPos pos) { Xray xray = Modules.get().get(Xray.class); if (wallHack.isActive() && wallHack.blocks.get().contains(state.getBlock())) { - if (MixinPlugin.isSodiumPresent || (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse())) return 0; + if (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse()) return 0; int alpha; @@ -130,7 +129,7 @@ public static int getAlpha(BlockState state, BlockPos pos) { return alpha; } else if (xray.isActive() && !wallHack.isActive() && xray.isBlocked(state.getBlock(), pos)) { - return (MixinPlugin.isSodiumPresent || (MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse())) ? 0 : xray.opacity.get(); + return ((MixinPlugin.isIrisPresent && IrisApi.getInstance().isShaderPackInUse())) ? 0 : xray.opacity.get(); } return -1; diff --git a/src/main/resources/meteor-client-sodium.mixins.json b/src/main/resources/meteor-client-sodium.mixins.json index a5c29dfd6a..70c6774d9b 100644 --- a/src/main/resources/meteor-client-sodium.mixins.json +++ b/src/main/resources/meteor-client-sodium.mixins.json @@ -7,12 +7,14 @@ "MeshVertexConsumerMixin", "SodiumBlockOcclusionCacheMixin", "SodiumBlockRendererMixin", + "SodiumDefaultFluidRendererMixin", "SodiumFluidRendererImplDefaultRenderContextMixin", "SodiumFluidRendererImplMixin", "SodiumLightDataAccessMixin", + "SodiumInnerPartitionBSPNodeMixin", "SodiumWorldRendererMixin" ], "injectors": { "defaultRequire": 1 } -} +} \ No newline at end of file