Merge pull request #434 from jaquadro/fix-fog-render
Fog: water, mix order, precision, post-processing
This commit is contained in:
commit
cce44a3910
1 changed files with 162 additions and 17 deletions
|
@ -1,11 +1,10 @@
|
|||
package biomesoplenty.client.fog;
|
||||
|
||||
import biomesoplenty.common.configuration.BOPConfigurationMisc;
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -13,6 +12,7 @@ import net.minecraft.entity.EntityLivingBase;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraftforge.client.event.EntityViewRenderEvent;
|
||||
|
@ -20,7 +20,6 @@ import net.minecraftforge.client.event.EntityViewRenderEvent.FogColors;
|
|||
import net.minecraftforge.common.ForgeModContainer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GLContext;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
|
@ -43,10 +42,25 @@ public class FogHandler
|
|||
int y = MathHelper.floor_double(player.posY);
|
||||
int z = MathHelper.floor_double(player.posZ);
|
||||
|
||||
int oldColour = ((int)(event.red * 255) & 255) << 16 | ((int)(event.green * 255) & 255) << 8 | (int)(event.blue * 255) & 255;
|
||||
int colour = getFogBlendColour(world, player, x, y, z, oldColour, event.renderPartialTicks);
|
||||
Block blockAtEyes = ActiveRenderInfo.getBlockAtEntityViewpoint(world, event.entity, (float)event.renderPartialTicks);
|
||||
if (blockAtEyes.getMaterial() == Material.lava)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.red = (colour >> 16 & 255) / 255.0F; event.green = (colour >> 8 & 255) / 255.0F; event.blue = (colour & 255) / 255.0F;
|
||||
Vec3 mixedColor;
|
||||
if (blockAtEyes.getMaterial() == Material.water)
|
||||
{
|
||||
mixedColor = getFogBlendColorWater(world, player, x, y, z, event.renderPartialTicks);
|
||||
}
|
||||
else
|
||||
{
|
||||
mixedColor = getFogBlendColour(world, player, x, y, z, event.red, event.green, event.blue, event.renderPartialTicks);
|
||||
}
|
||||
|
||||
event.red = (float)mixedColor.xCoord;
|
||||
event.green = (float)mixedColor.yCoord;
|
||||
event.blue = (float)mixedColor.zCoord;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +164,125 @@ public class FogHandler
|
|||
}
|
||||
}
|
||||
|
||||
public static int getFogBlendColour(World world, Entity playerEntity, int playerX, int playerY, int playerZ, int defaultColour, double renderPartialTicks)
|
||||
private static Vec3 postProcessColor (World world, EntityLivingBase player, float r, float g, float b, double renderPartialTicks)
|
||||
{
|
||||
double darkScale = (player.lastTickPosY + (player.posY - player.lastTickPosY) * renderPartialTicks) * world.provider.getVoidFogYFactor();
|
||||
|
||||
if (player.isPotionActive(Potion.blindness))
|
||||
{
|
||||
int duration = player.getActivePotionEffect(Potion.blindness).getDuration();
|
||||
darkScale *= (duration < 20) ? (1 - duration / 20f) : 0;
|
||||
}
|
||||
|
||||
if (darkScale < 1)
|
||||
{
|
||||
darkScale = (darkScale < 0) ? 0 : darkScale * darkScale;
|
||||
r *= darkScale;
|
||||
g *= darkScale;
|
||||
b *= darkScale;
|
||||
}
|
||||
|
||||
if (player.isPotionActive(Potion.nightVision))
|
||||
{
|
||||
// Get night vision brightness, accounting for wavering at end of potion effect
|
||||
int duration = player.getActivePotionEffect(Potion.nightVision).getDuration();
|
||||
float brightness = (duration > 200) ? 1 : 0.7f + MathHelper.sin((float)((duration - renderPartialTicks) * Math.PI * 0.2f)) * 0.3f;
|
||||
|
||||
// Find scale to bring r, g, or b to 1.0
|
||||
// Vanilla will actually set the colors to +Infinity if all components are 0, explaining the terrible
|
||||
// interaction between the blindness and night vision potion effects.
|
||||
float scale = 1 / r;
|
||||
scale = Math.min(scale, 1 / g);
|
||||
scale = Math.min(scale, 1 / b);
|
||||
|
||||
r = r * (1 - brightness) + r * scale * brightness;
|
||||
g = g * (1 - brightness) + g * scale * brightness;
|
||||
b = b * (1 - brightness) + b * scale * brightness;
|
||||
}
|
||||
|
||||
if (Minecraft.getMinecraft().gameSettings.anaglyph)
|
||||
{
|
||||
float aR = (r * 30 + g * 59 + b * 11) / 100;
|
||||
float aG = (r * 30 + g * 70) / 100;
|
||||
float aB = (r * 30 + b * 70) / 100;
|
||||
|
||||
r = aR;
|
||||
g = aG;
|
||||
b = aB;
|
||||
}
|
||||
|
||||
return Vec3.createVectorHelper(r, g, b);
|
||||
}
|
||||
|
||||
private static Vec3 getFogBlendColorWater (World world, EntityLivingBase playerEntity, int playerX, int playerY, int playerZ, double renderPartialTicks)
|
||||
{
|
||||
int distance = 2;
|
||||
float rBiomeFog = 0;
|
||||
float gBiomeFog = 0;
|
||||
float bBiomeFog = 0;
|
||||
|
||||
for (int x = -distance; x <= distance; ++x)
|
||||
{
|
||||
for (int z = -distance; z <= distance; ++z)
|
||||
{
|
||||
BiomeGenBase biome = world.getBiomeGenForCoords(playerX + x, playerZ + z);
|
||||
int waterColorMult = biome.waterColorMultiplier;
|
||||
|
||||
float rPart = (waterColorMult & 0xFF0000) >> 16;
|
||||
float gPart = (waterColorMult & 0x00FF00) >> 8;
|
||||
float bPart = waterColorMult & 0x0000FF;
|
||||
|
||||
if (x == -distance)
|
||||
{
|
||||
double xDiff = 1 - (playerEntity.posX - playerX);
|
||||
rPart *= xDiff;
|
||||
gPart *= xDiff;
|
||||
bPart *= xDiff;
|
||||
}
|
||||
else if (x == distance)
|
||||
{
|
||||
double xDiff = playerEntity.posX - playerX;
|
||||
rPart *= xDiff;
|
||||
gPart *= xDiff;
|
||||
bPart *= xDiff;
|
||||
}
|
||||
|
||||
if (z == -distance)
|
||||
{
|
||||
double zDiff = 1 - (playerEntity.posZ - playerZ);
|
||||
rPart *= zDiff;
|
||||
gPart *= zDiff;
|
||||
bPart *= zDiff;
|
||||
}
|
||||
else if (z == distance)
|
||||
{
|
||||
double zDiff = playerEntity.posZ - playerZ;
|
||||
rPart *= zDiff;
|
||||
gPart *= zDiff;
|
||||
bPart *= zDiff;
|
||||
}
|
||||
|
||||
rBiomeFog += rPart;
|
||||
gBiomeFog += gPart;
|
||||
bBiomeFog += bPart;
|
||||
}
|
||||
}
|
||||
|
||||
rBiomeFog /= 255f;
|
||||
gBiomeFog /= 255f;
|
||||
bBiomeFog /= 255f;
|
||||
|
||||
float weight = (distance * 2) * (distance * 2);
|
||||
float respirationLevel = (float)EnchantmentHelper.getRespiration(playerEntity) * 0.2F;
|
||||
|
||||
float rMixed = (rBiomeFog * 0.02f + respirationLevel) / weight;
|
||||
float gMixed = (gBiomeFog * 0.02f + respirationLevel) / weight;
|
||||
float bMixed = (bBiomeFog * 0.2f + respirationLevel) / weight;
|
||||
|
||||
return postProcessColor(world, playerEntity, rMixed, gMixed, bMixed, renderPartialTicks);
|
||||
}
|
||||
|
||||
private static Vec3 getFogBlendColour(World world, EntityLivingBase playerEntity, int playerX, int playerY, int playerZ, float defR, float defG, float defB, double renderPartialTicks)
|
||||
{
|
||||
GameSettings settings = Minecraft.getMinecraft().gameSettings;
|
||||
int[] ranges = ForgeModContainer.blendRanges;
|
||||
|
@ -223,6 +355,15 @@ public class FogHandler
|
|||
}
|
||||
}
|
||||
|
||||
if (weightBiomeFog == 0)
|
||||
{
|
||||
return Vec3.createVectorHelper(defR, defG, defB);
|
||||
}
|
||||
|
||||
rBiomeFog /= 255f;
|
||||
gBiomeFog /= 255f;
|
||||
bBiomeFog /= 255f;
|
||||
|
||||
// Calculate day / night / weather scale for BiomeFog component
|
||||
float celestialAngle = world.getCelestialAngle((float)renderPartialTicks);
|
||||
float baseScale = MathHelper.clamp_float(MathHelper.cos(celestialAngle * (float)Math.PI * 2.0F) * 2.0F + 0.5F, 0, 1);
|
||||
|
@ -245,20 +386,24 @@ public class FogHandler
|
|||
bScale *= 1 - thunderStrength * 0.5f;
|
||||
}
|
||||
|
||||
// Mix default fog component with BiomeFog component
|
||||
float rDefault = (defaultColour & 0xFF0000) >> 16;
|
||||
float gDefault = (defaultColour & 0x00FF00) >> 8;
|
||||
float bDefault = defaultColour & 0x0000FF;
|
||||
// Apply post-processing to BiomeFog component. Default color was already processed by Vanilla.
|
||||
rBiomeFog *= rScale / weightBiomeFog;
|
||||
gBiomeFog *= gScale / weightBiomeFog;
|
||||
bBiomeFog *= bScale / weightBiomeFog;
|
||||
|
||||
Vec3 processedColor = postProcessColor(world, playerEntity, rBiomeFog, gBiomeFog, bBiomeFog, renderPartialTicks);
|
||||
rBiomeFog = (float)processedColor.xCoord;
|
||||
gBiomeFog = (float)processedColor.yCoord;
|
||||
bBiomeFog = (float)processedColor.zCoord;
|
||||
|
||||
// Mix default fog component with BiomeFog component
|
||||
float weightMixed = (distance * 2) * (distance * 2);
|
||||
float weightDefault = weightMixed - weightBiomeFog;
|
||||
|
||||
float rMixed = (rBiomeFog * rScale + rDefault * weightDefault) / weightMixed;
|
||||
float gMixed = (gBiomeFog * gScale + gDefault * weightDefault) / weightMixed;
|
||||
float bMixed = (bBiomeFog * bScale + bDefault * weightDefault) / weightMixed;
|
||||
processedColor.xCoord = (rBiomeFog * weightBiomeFog + defR * weightDefault) / weightMixed;
|
||||
processedColor.yCoord = (gBiomeFog * weightBiomeFog + defG * weightDefault) / weightMixed;
|
||||
processedColor.zCoord = (bBiomeFog * weightBiomeFog + defB * weightDefault) / weightMixed;
|
||||
|
||||
int multiplier = ((int)rMixed & 255) << 16 | ((int)gMixed & 255) << 8 | (int)bMixed & 255;
|
||||
|
||||
return multiplier;
|
||||
return processedColor;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue