Improve the lighting on local worlds

ClientWorld apparently doesn't actually know what the lighting is anywhere, so we will have to find another way to determine shadows on servers.
This commit is contained in:
James Seibel
2021-10-16 13:45:31 -05:00
parent a122015f6d
commit a0c14c86ca
3 changed files with 85 additions and 66 deletions
@@ -18,6 +18,14 @@
package com.seibel.lod.builders.lodBuilding;
import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.HorizontalResolution;
@@ -25,10 +33,26 @@ import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.*;
import com.seibel.lod.util.ColorUtil;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.block.*;
import net.minecraft.block.AbstractPlantBlock;
import net.minecraft.block.AbstractTopPlantBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.BushBlock;
import net.minecraft.block.FlowerBlock;
import net.minecraft.block.GrassBlock;
import net.minecraft.block.IGrowable;
import net.minecraft.block.LeavesBlock;
import net.minecraft.block.TallGrassBlock;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -45,22 +69,16 @@ import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.client.model.data.ModelDataMap;
import java.awt.*;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* This object is in charge of creating Lod related objects. (specifically: Lod
* World, Dimension, and Region objects)
* This object is in charge of creating Lod related objects.
*
* @author Cola
* @author Leonardo Amato
* @author James Seibel
* @version 10-9-2021
* @version 10-16-2021
*/
public class LodBuilder
{
@@ -415,33 +433,43 @@ public class LodBuilder
/** Gets the light value for the given block position */
private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean hasCeiling, boolean hasSkyLight, boolean topBlock)
{
int skyLight;
int skyLight = 0;
int blockLight;
// 1 means the lighting is a guess
int isDefault = 0;
if (mc.getClientWorld() == null)
ClientWorld clientWorld = mc.getClientWorld();
if (clientWorld == null)
return 0;
ClientWorld world = mc.getClientWorld();
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(clientWorld.dimensionType());
int blockBrightness = chunk.getLightEmission(blockPos);
// get the air block above or below this block
if (hasCeiling && topBlock)
blockPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
else
blockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ());
if (!hasSkyLight && hasCeiling)
skyLight = 0;
else if (topBlock)
skyLight = DEFAULT_MAX_LIGHT;
if (serverWorld != null)
{
// server world sky light (always accurate)
skyLight = serverWorld.getBrightness(LightType.SKY, blockPos);
}
else
{
if (LodConfig.CLIENT.worldGenerator.useExperimentalSkyLight.get())
// client world sky light (almost never accurate)
// estimate what the lighting should be
if (!hasSkyLight && hasCeiling)
skyLight = 0;
else if (topBlock)
skyLight = DEFAULT_MAX_LIGHT;
else
{
skyLight = world.getBrightness(LightType.SKY, blockPos);
skyLight = clientWorld.getBrightness(LightType.SKY, blockPos);
if (!chunk.isLightCorrect() && (skyLight == 0 || skyLight == 15))
{
// we don't know what the light here is,
@@ -455,21 +483,12 @@ public class LodBuilder
skyLight = 0;
}
}
else
{
if (blockPos.getY() >= mc.getClientWorld().getSeaLevel() - 5)
{
skyLight = 12;
isDefault = 1;
}
else
skyLight = 0;
}
//if (skyLight == 15)
// ClientProxy.LOGGER.warn("skylight 15 while not top block");
}
blockLight = world.getBrightness(LightType.BLOCK, blockPos);
int blockBrightness = chunk.getLightEmission(blockPos);
blockLight = clientWorld.getBrightness(LightType.BLOCK, blockPos);
blockLight = LodUtil.clamp(0, blockLight + blockBrightness, DEFAULT_MAX_LIGHT);
return blockLight + (skyLight << 4) + (isDefault << 8);
@@ -18,20 +18,34 @@
package com.seibel.lod.config;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.io.WritingMode;
import com.seibel.lod.ModInfo;
import com.seibel.lod.enums.*;
import com.seibel.lod.enums.BufferRebuildTimes;
import com.seibel.lod.enums.DebugMode;
import com.seibel.lod.enums.DetailDropOff;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.FogDistance;
import com.seibel.lod.enums.FogDrawOverride;
import com.seibel.lod.enums.GenerationPriority;
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;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* This handles any configuration the user has access to.
@@ -196,7 +210,6 @@ public class LodConfig
public final ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration;
public final ForgeConfigSpec.EnumValue<HorizontalScale> horizontalScale;
public final ForgeConfigSpec.EnumValue<HorizontalQuality> horizontalQuality;
public final ForgeConfigSpec.BooleanValue useExperimentalSkyLight;
public final ForgeConfigSpec.BooleanValue avoidBlockWithNoCollision;
public final ForgeConfigSpec.BooleanValue avoidNonFullBlock;
@@ -321,21 +334,16 @@ public class LodConfig
+ " https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/35 \n")
.define("allowUnstableFeatureGeneration", false);
useExperimentalSkyLight = builder
.comment("\n\n"
+ " Change how sky light value is calculated in the fake chunks \n")
.define("use experimental sky light system", false);
avoidBlockWithNoCollision = builder
.comment("\n\n"
+ " if true avoid block that have no collision box in the generation \n"
+ " grass, \n")
.define("avoid Block With No Collision", false);
+ " If true LODs will only use blocks that have collisions when generating. \n"
+ " Turning this on will make plains smoother since the tall grass won't be used. \n")
.define("avoid Block With No Collision", true);
avoidNonFullBlock = builder
.comment("\n\n"
+ " If you are a Java wizard, check out the git issue here: \n"
+ " If you are a Java wizard, check out the git issue here: \n")
+ " If true LODs will only show full bocks when generating. \n"
+ " Turning this on will make plains smoother since the tall grass won't be used. \n")
.define("avoid Non Full Block", false);
builder.pop();
}
@@ -41,8 +41,6 @@ import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.profiler.IProfiler;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunk;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.world.BlockEvent;
@@ -182,7 +180,7 @@ public class ClientProxy
// LodConfig.CLIENT.graphics.lodChunkRenderDistance.set(64);
// LodConfig.CLIENT.worldGenerator.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
// LodConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.set(false);
// LodConfig.CLIENT.buffers.rebuildTimes.set(BufferRebuildTimes.FREQUENT);
LodConfig.CLIENT.debugging.enableDebugKeybindings.set(true);
@@ -210,13 +208,7 @@ public class ClientProxy
@SubscribeEvent
public void chunkLoadEvent(ChunkEvent.Load event)
{
// Optifine also returns chunks from this event
// which are slightly different then normal Minecraft chunks.
IChunk chunk = event.getChunk();
if (chunk.getClass() != Chunk.class)
return;
lodBuilder.generateLodNodeAsync(chunk, lodWorld, event.getWorld(), DistanceGenerationMode.SERVER);
lodBuilder.generateLodNodeAsync(event.getChunk(), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER);
}
@SubscribeEvent