Add the overdraw

Overdraw renders LODs on top of vanilla chunks based with  three different settings.
This commit is contained in:
James Seibel
2021-10-10 21:31:45 -05:00
parent 9d1a9eb9f3
commit 732476b454
4 changed files with 101 additions and 11 deletions
@@ -38,7 +38,9 @@ import com.seibel.lod.enums.HorizontalQuality;
import com.seibel.lod.enums.HorizontalResolution;
import com.seibel.lod.enums.HorizontalScale;
import com.seibel.lod.enums.LodTemplate;
import com.seibel.lod.enums.VanillaOverdraw;
import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.util.LodUtil;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -49,7 +51,7 @@ import net.minecraftforge.fml.config.ModConfig;
* This handles any configuration the user has access to.
*
* @author James Seibel
* @version 10-9-2021
* @version 10-10-2021
*/
@Mod.EventBusSubscriber
public class LodConfig
@@ -99,6 +101,7 @@ public class LodConfig
public final ForgeConfigSpec.BooleanValue drawLods;
public final ForgeConfigSpec.EnumValue<VanillaOverdraw> vanillaOverdraw;
Graphics(ForgeConfigSpec.Builder builder)
{
@@ -183,6 +186,16 @@ public class LodConfig
+ " distances higher than 128 \n")
.define("alwaysDrawAtMaxQuality", false);
vanillaOverdraw = builder
.comment("\n\n"
+ " How often should LODs be drawn on top of regular chunks? \n"
+ " HALF and ALWAYS will prevent holes in the world, but may look odd on transparent blocks. \n"
+ VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n"
+ VanillaOverdraw.HALF + ": LODs will render on top of distant vanilla chunks to hide holes in the world. \n"
+ " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " " + VanillaOverdraw.HALF + " defaults works the same as " + VanillaOverdraw.ALWAYS + ". \n"
+ VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n")
.defineEnum("vanillaOverdraw", VanillaOverdraw.HALF);
builder.pop();
}
}
@@ -207,7 +220,6 @@ public class LodConfig
+ " overhangs, caves, floating islands, ect. \n"
+ " Higher options will use more memory and lower performance. \n"
+ " " + VerticalQuality.LOW + ": uses at max 2 columns per position. \n"
+ " " + VerticalQuality.MEDIUM + ": uses at max 4 columns per position. \n"
+ " " + VerticalQuality.HIGH + ": uses at max 8 columns per position. \n")
.defineEnum("Vertical Quality", VerticalQuality.MEDIUM);
@@ -0,0 +1,23 @@
package com.seibel.lod.enums;
/**
* None, Half, Always
*
* <p>
* This represents how far the LODs should overlap with
* the vanilla Minecraft terrain.
*
* @author James Seibel
* @version 10-10-2021
*/
public enum VanillaOverdraw
{
/** Never draw LODs where a minecraft chunk could be. */
NEVER,
/** Draw LODs over the farther minecraft chunks. */
HALF,
/** Draw LODs over all minecraft chunks. */
ALWAYS,
}
@@ -18,6 +18,10 @@
package com.seibel.lod.proxy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
import com.seibel.lod.builders.lodBuilding.LodBuilder;
@@ -25,6 +29,7 @@ import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker;
import com.seibel.lod.builders.worldGeneration.LodWorldGenerator;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.VanillaOverdraw;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.objects.RegionPos;
@@ -34,6 +39,7 @@ import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.profiler.IProfiler;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.client.event.InputEvent;
@@ -42,9 +48,6 @@ import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
/**
* This handles all events sent to the client,
@@ -178,8 +181,7 @@ public class ClientProxy
// LodConfig.CLIENT.graphics.fogDistance.set(FogDistance.FAR);
// LodConfig.CLIENT.graphics.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
// LodConfig.CLIENT.graphics.shadingMode.set(ShadingMode.DARKEN_SIDES);
// LodConfig.CLIENT.graphics.brightnessMultiplier.set(1.0);
// LodConfig.CLIENT.graphics.saturationMultiplier.set(1.0);
LodConfig.CLIENT.graphics.vanillaOverdraw.set(VanillaOverdraw.HALF);
// LodConfig.CLIENT.worldGenerator.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
// LodConfig.CLIENT.graphics.lodChunkRenderDistance.set(64);
+57 -4
View File
@@ -23,6 +23,8 @@ import java.io.File;
import java.util.HashSet;
import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.VanillaOverdraw;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.wrappers.MinecraftWrapper;
@@ -54,6 +56,12 @@ public class LodUtil
{
private static final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
/**
* vanilla render distances less than or equal to this will not allow partial
* overdraw. The VanillaOverdraw with either be ALWAYS or NEVER.
*/
public static final int MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW = 5;
/** The maximum number of LODs that can be rendered vertically */
public static final int MAX_NUMBER_OF_VERTICAL_LODS = 32;
@@ -359,21 +367,66 @@ public class LodUtil
int chunkRenderDist = mc.getRenderDistance();
ChunkPos centerChunk = new ChunkPos(playerPos);
// skip chunks that are already going to be rendered by Minecraft
int skipRadius;
VanillaOverdraw overdraw = LodConfig.CLIENT.graphics.vanillaOverdraw.get();
switch (overdraw)
{
case ALWAYS:
// don't skip any positions
return new HashSet<ChunkPos>();
case HALF:
// for small render distances just skip everything
// since the distance isn't far enough
// where partial skipping doesn't make sense
if (chunkRenderDist <= MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW)
{
// don't skip any positions
return new HashSet<ChunkPos>();
}
else
{
// only skip positions that are greater than
// half the render distance
skipRadius = (int) Math.ceil(chunkRenderDist / 2.0);
}
break;
default:
case NEVER:
// skip chunks in render distance that are rendered
// by vanilla minecraft
skipRadius = 0;
break;
}
// get the chunks that are going to be rendered by Minecraft
HashSet<ChunkPos> posToSkip = getRenderedChunks();
// go through each chunk within the normal view distance
// apply special cases to those positions
for (int x = centerChunk.x - chunkRenderDist; x < centerChunk.x + chunkRenderDist; x++)
{
for (int z = centerChunk.z - chunkRenderDist; z < centerChunk.z + chunkRenderDist; z++)
{
// if the skipRadius is being used...
if (skipRadius != 0 &&
((x <= centerChunk.x - skipRadius || x >= centerChunk.x + skipRadius)
|| (z <= centerChunk.z - skipRadius || z >= centerChunk.z + skipRadius)))
{
// ...remove everything outside the skipRadius
posToSkip.remove(new ChunkPos(x, z));
continue;
}
if (!lodDim.doesDataExist(LodUtil.CHUNK_DETAIL_LEVEL, x, z))
continue;
long data = lodDim.getSingleData(LodUtil.CHUNK_DETAIL_LEVEL, x, z);
short lodAverageHeight = DataPointUtil.getHeight(data);
if (playerPos.getY() <= lodAverageHeight)
{
// don't draw LODs that are taller than the player