From 4abeedf921832dcadd61160a34dbb7d25a0c97be Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 20 Jan 2024 22:00:30 -0500 Subject: [PATCH] Implement proper Sodium biome blending & entity distance sliders --- .../client/gui/SodiumGameOptionPages.java | 14 ++--- .../sodium/client/gui/SodiumGameOptions.java | 3 ++ .../control/ControlValueFormatter.java | 2 +- .../blender/ConfigurableColorBlender.java | 8 +-- .../client/world/SodiumBlockAccess.java | 12 +++++ .../mods/sodium/client/world/WorldSlice.java | 26 +++++++++- .../sodium/client/world/WorldSliceLocal.java | 12 +++-- .../client/world/biome/BiomeColorCache.java | 5 +- .../MixinBiomeColorHelper.java | 52 +++++++++++++++++++ .../chunk_rendering/MixinRenderGlobal.java | 4 ++ .../resources/assets/sodium/lang/en_us.lang | 2 + src/main/resources/sodium.mixins.json | 1 + 12 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 src/main/java/me/jellysquid/mods/sodium/client/world/SodiumBlockAccess.java create mode 100644 src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinBiomeColorHelper.java diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java index bd29bff4a..4292be24a 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -173,21 +173,21 @@ public static OptionPage quality() { .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) .build()) // TODO - /*.add(OptionImpl.createBuilder(int.class, vanillaOpts) - .setName(new TextComponentTranslation("options.biomeBlendRadius")) + .add(OptionImpl.createBuilder(int.class, sodiumOpts) + .setName(new TextComponentTranslation("sodium.options.biome_blend.name")) .setTooltip(new TextComponentTranslation("sodium.options.biome_blend.tooltip")) .setControl(option -> new SliderControl(option, 0, 7, 1, ControlValueFormatter.quantityOrDisabled("sodium.options.biome_blend.value", "gui.none"))) - .setBinding((opts, value) -> opts.biomeBlendRadius = value, opts -> opts.biomeBlendRadius) + .setBinding((opts, value) -> opts.quality.biomeBlendRadius = value, opts -> opts.quality.biomeBlendRadius) .setImpact(OptionImpact.LOW) .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) .build()) - .add(OptionImpl.createBuilder(int.class, vanillaOpts) - .setName(new TextComponentTranslation("options.entityDistanceScaling")) + .add(OptionImpl.createBuilder(int.class, sodiumOpts) + .setName(new TextComponentTranslation("sodium.options.entity_distance.name")) .setTooltip(new TextComponentTranslation("sodium.options.entity_distance.tooltip")) .setControl(option -> new SliderControl(option, 50, 500, 25, ControlValueFormatter.percentage())) - .setBinding((opts, value) -> opts.entityDistanceScaling = value / 100.0F, opts -> Math.round(opts.entityDistanceScaling * 100.0F)) + .setBinding((opts, value) -> opts.quality.entityDistanceScaling = value / 100.0F, opts -> Math.round(opts.quality.entityDistanceScaling * 100.0F)) .setImpact(OptionImpact.MEDIUM) - .build())*/ + .build()) .add(OptionImpl.createBuilder(boolean.class, vanillaOpts) .setName(new TextComponentTranslation("options.entityShadows")) .setTooltip(new TextComponentTranslation("sodium.options.entity_shadows.tooltip")) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java index 6114f0446..9348fb906 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java @@ -50,6 +50,9 @@ public static class QualitySettings { public GraphicsQuality weatherQuality = GraphicsQuality.DEFAULT; public GraphicsQuality leavesQuality = GraphicsQuality.DEFAULT; + public int biomeBlendRadius = 2; + public float entityDistanceScaling = 1.0F; + public boolean enableVignette = true; public boolean enableClouds = true; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java index 3c45915b5..454a884a0 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java @@ -27,7 +27,7 @@ static ControlValueFormatter brightness() { String format(int value); static ControlValueFormatter percentage() { - return (v) -> new TextComponentTranslation(v + "%").getFormattedText(); + return (v) -> v + "%"; } static ControlValueFormatter multiplier() { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/quad/blender/ConfigurableColorBlender.java b/src/main/java/me/jellysquid/mods/sodium/client/model/quad/blender/ConfigurableColorBlender.java index 6041e898f..64b305d09 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/quad/blender/ConfigurableColorBlender.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/quad/blender/ConfigurableColorBlender.java @@ -1,5 +1,6 @@ package me.jellysquid.mods.sodium.client.model.quad.blender; +import me.jellysquid.mods.sodium.client.SodiumClientMod; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -13,12 +14,11 @@ class ConfigurableColorBlender implements BiomeColorBlender { public ConfigurableColorBlender(Minecraft client) { this.defaultBlender = new FlatBiomeColorBlender(); - this.smoothBlender = isSmoothBlendingEnabled(client) ? new SmoothBiomeColorBlender() : this.defaultBlender; + this.smoothBlender = isSmoothBlendingEnabled() ? new SmoothBiomeColorBlender() : this.defaultBlender; } - // TODO - private static boolean isSmoothBlendingEnabled(Minecraft client) { - return true/*client.gameSettings.biomeBlendRadius > 0*/; + private static boolean isSmoothBlendingEnabled() { + return SodiumClientMod.options().quality.biomeBlendRadius > 0; } @Override diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/SodiumBlockAccess.java b/src/main/java/me/jellysquid/mods/sodium/client/world/SodiumBlockAccess.java new file mode 100644 index 000000000..f3ba6fa0c --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/SodiumBlockAccess.java @@ -0,0 +1,12 @@ +package me.jellysquid.mods.sodium.client.world; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.biome.BiomeColorHelper; + +/** + * Contains extensions to the vanilla {@link IBlockAccess}. + */ +public interface SodiumBlockAccess extends IBlockAccess { + int getBlockTint(BlockPos pos, BiomeColorHelper.ColorResolver resolver); +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java index c40bc17e0..74b106b1d 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java @@ -37,7 +37,7 @@ * * Object pooling should be used to avoid huge allocations as this class contains many large arrays. */ -public class WorldSlice implements IBlockAccess { +public class WorldSlice implements SodiumBlockAccess { // The number of blocks on each axis in a section. private static final int SECTION_BLOCK_LENGTH = 16; @@ -378,6 +378,30 @@ public Biome getBiome(BlockPos pos) { return Biomes.PLAINS; } + @Override + public int getBlockTint(BlockPos pos, BiomeColorHelper.ColorResolver resolver) { + if(!blockBoxContains(this.volume, pos.getX(), pos.getY(), pos.getZ())) { + return resolver.getColorAtPos(Biomes.PLAINS, pos); + } + + BiomeColorCache cache; + + if (this.prevColorResolver == resolver) { + cache = this.prevColorCache; + } else { + cache = this.biomeColorCaches.get(resolver); + + if (cache == null) { + this.biomeColorCaches.put(resolver, cache = new BiomeColorCache(resolver, this)); + } + + this.prevColorResolver = resolver; + this.prevColorCache = cache; + } + + return cache.getBlendedColor(pos); + } + @Override public int getStrongPower(BlockPos pos, EnumFacing direction) { IBlockState state = this.getBlockState(pos); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSliceLocal.java b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSliceLocal.java index 21b715244..a3a38b2d3 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSliceLocal.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSliceLocal.java @@ -7,6 +7,7 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.WorldType; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeColorHelper; import javax.annotation.Nullable; @@ -14,10 +15,10 @@ * Wrapper object used to defeat identity comparisons in mods. Since vanilla provides a unique object to them for each * subchunk, we do the same. */ -public class WorldSliceLocal implements IBlockAccess { - private final IBlockAccess view; +public class WorldSliceLocal implements SodiumBlockAccess { + private final SodiumBlockAccess view; - public WorldSliceLocal(IBlockAccess view) { + public WorldSliceLocal(SodiumBlockAccess view) { this.view = view; } @@ -61,4 +62,9 @@ public WorldType getWorldType() { public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default) { return view.isSideSolid(pos, side, _default); } + + @Override + public int getBlockTint(BlockPos pos, BiomeColorHelper.ColorResolver resolver) { + return view.getBlockTint(pos, resolver); + } } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/biome/BiomeColorCache.java b/src/main/java/me/jellysquid/mods/sodium/client/world/biome/BiomeColorCache.java index 9fd3fcb65..1e9bc37ad 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/world/biome/BiomeColorCache.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/biome/BiomeColorCache.java @@ -1,5 +1,7 @@ package me.jellysquid.mods.sodium.client.world.biome; +import me.jellysquid.mods.sodium.client.SodiumClientMod; +import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions; import me.jellysquid.mods.sodium.client.util.color.ColorARGB; import me.jellysquid.mods.sodium.client.util.math.ChunkSectionPos; import me.jellysquid.mods.sodium.client.world.WorldSlice; @@ -30,8 +32,7 @@ public class BiomeColorCache { public BiomeColorCache(BiomeColorHelper.ColorResolver resolver, WorldSlice slice) { this.resolver = resolver; this.slice = slice; - // TODO - this.radius = 3/*Minecraft.getMinecraft().gameSettings.biomeBlendRadius*/; + this.radius = SodiumClientMod.options().quality.biomeBlendRadius; ChunkSectionPos origin = this.slice.getOrigin(); diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinBiomeColorHelper.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinBiomeColorHelper.java new file mode 100644 index 000000000..3fac2f9b9 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinBiomeColorHelper.java @@ -0,0 +1,52 @@ +package me.jellysquid.mods.sodium.mixin.features.chunk_rendering; + +import me.jellysquid.mods.sodium.client.SodiumClientMod; +import me.jellysquid.mods.sodium.client.world.SodiumBlockAccess; +import me.jellysquid.mods.sodium.client.world.WorldSlice; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeColorHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(value = BiomeColorHelper.class, priority = 1200) +public class MixinBiomeColorHelper { + /** + * @author embeddedt + * @reason reduce allocation rate, use Sodium's biome cache, use configurable biome blending + */ + @Overwrite + private static int getColorAtPos(IBlockAccess blockAccess, BlockPos pos, BiomeColorHelper.ColorResolver colorResolver) + { + if (blockAccess instanceof SodiumBlockAccess) { + // Use Sodium's more efficient biome cache + return ((SodiumBlockAccess)blockAccess).getBlockTint(pos, colorResolver); + } + int radius = SodiumClientMod.options().quality.biomeBlendRadius; + if (radius == 0) { + return colorResolver.getColorAtPos(blockAccess.getBiome(pos), pos); + } else { + int blockCount = (radius * 2 + 1) * (radius * 2 + 1); + + int i = 0; + int j = 0; + int k = 0; + + BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + + for(int z = -radius; z <= radius; z++) { + for(int x = -radius; x <= radius; x++) { + mutablePos.setPos(pos.getX() + x, pos.getY(), pos.getZ() + z); + int l = colorResolver.getColorAtPos(blockAccess.getBiome(mutablePos), mutablePos); + i += (l & 16711680) >> 16; + j += (l & 65280) >> 8; + k += l & 255; + } + } + + return (i / blockCount & 255) << 16 | (j / blockCount & 255) << 8 | k / blockCount & 255; + } + + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinRenderGlobal.java b/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinRenderGlobal.java index 012601cd9..b96ef08c9 100644 --- a/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinRenderGlobal.java +++ b/src/main/java/me/jellysquid/mods/sodium/mixin/features/chunk_rendering/MixinRenderGlobal.java @@ -1,6 +1,7 @@ package me.jellysquid.mods.sodium.mixin.features.chunk_rendering; import com.llamalad7.mixinextras.sugar.Local; +import me.jellysquid.mods.sodium.client.SodiumClientMod; import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; @@ -12,6 +13,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.chunk.Chunk; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -49,6 +51,8 @@ private void renderEntities(Entity renderViewEntity, ICamera camera, float parti int pass = net.minecraftforge.client.MinecraftForgeClient.getRenderPass(); EntityPlayerSP player = this.mc.player; BlockPos.MutableBlockPos entityBlockPos = new BlockPos.MutableBlockPos(); + // Apply entity distance scaling + Entity.setRenderDistanceWeight(MathHelper.clamp((double)this.mc.gameSettings.renderDistanceChunks / 8.0D, 1.0D, 2.5D) * SodiumClientMod.options().quality.entityDistanceScaling); for(Entity entity : loadedEntityList) { // Skip entities that shouldn't render in this pass if(!entity.shouldRenderInPass(pass)) { diff --git a/src/main/resources/assets/sodium/lang/en_us.lang b/src/main/resources/assets/sodium/lang/en_us.lang index b1ec841ce..df9960457 100644 --- a/src/main/resources/assets/sodium/lang/en_us.lang +++ b/src/main/resources/assets/sodium/lang/en_us.lang @@ -26,8 +26,10 @@ sodium.options.leaves_quality.tooltip=Controls the quality of leaves. sodium.options.particle_quality.name=Particle Quality sodium.options.particle_quality.tooltip=Controls the maximum number of particles which can be present on screen at any one time. sodium.options.smooth_lighting.tooltip=Controls whether blocks will be smoothly lit and shaded. This slightly increases the amount of time needed to re-build a chunk, but doesn't affect frame rates. +sodium.options.biome_blend.name=Biome Blend sodium.options.biome_blend.value=%s block(s) sodium.options.biome_blend.tooltip=Controls the range which biomes will be sampled for block colorization. Higher values greatly increase the amount of time it takes to build chunks for diminishing improvements in quality. +sodium.options.entity_distance.name=Entity Distance sodium.options.entity_distance.tooltip=Controls how far away entities can render from the player. Higher values increase the render distance at the expense of frame rates. sodium.options.entity_shadows.tooltip=If enabled, basic shadows will be rendered beneath mobs and other entities. sodium.options.vignette.name=Vignette diff --git a/src/main/resources/sodium.mixins.json b/src/main/resources/sodium.mixins.json index 7a8ca32a0..f2d37ad60 100644 --- a/src/main/resources/sodium.mixins.json +++ b/src/main/resources/sodium.mixins.json @@ -26,6 +26,7 @@ "features.buffer_builder.fast_advance.MixinVertexFormat", //"features.buffer_builder.fast_sort.MixinBufferBuilder", "features.chunk_rendering.AccessorActiveRenderInfo", + "features.chunk_rendering.MixinBiomeColorHelper", "features.chunk_rendering.MixinChunkBuilder", "features.chunk_rendering.MixinClientChunkManager", "features.chunk_rendering.MixinClientWorld",