Biomes change color too brusquely: they change color within 4 or 5 blocks and tall grass/fern/vines and sky color don't fade at all. This issue is present since Anvil file format was added and it's very noticeable when there is a river in the jungle biome. I downloaded 12w03a, when jungles where added, but world used the old format, so i have a bunch of screenshots for comparison (the first and the last screenshots are from 1.4.3pre, the others are from 12w03a).
Linked issues
is duplicated by 1
Attachments
Comments 21
The narrow distance over which they change color is to reduce CPU loading (it calculates the average over few blocks range, and that for every block needing it).
However, for vines, tall grass and ferns, there seems to be no averaging at all. Lets add it.
Fix
(MCP naming etc. etc.)
ColorizerFoliage
// Added method, code copied from BlockLeaves
public static int calculateAverageColorMultiplier(IBlockAccess blockAccess, int x, int z) {
int color1 = 0;
int color2 = 0;
int color3 = 0;
for (int zi = -1; zi <= 1; ++zi) {
for (int xi = -1; xi <= 1; ++xi) {
int baseColor = blockAccess.getBiomeGenForCoords(x + xi, z + zi).getBiomeFoliageColor();
color1 += (baseColor & 16711680) >> 16;
color2 += (baseColor & 65280) >> 8;
color3 += baseColor & 255;
}
}
return (color1 / 9 & 255) << 16 | (color2 / 9 & 255) << 8 | color3 / 9 & 255;
}
ColorizerGrass
// Added method, code copied from BlockGrass. Yuck 99% duplicate, but Mojang seems to like it so anyway:
public static int calculateAverageColorMultiplier(IBlockAccess blockAccess, int x, int z) {
int color1 = 0;
int color2 = 0;
int color3 = 0;
for (int zi = -1; zi <= 1; ++zi) {
for (int xi = -1; xi <= 1; ++xi) {
int baseColor = blockAccess.getBiomeGenForCoords(x + xi, z + zi).getBiomeGrassColor();
color1 += (baseColor & 16711680) >> 16;
color2 += (baseColor & 65280) >> 8;
color3 += baseColor & 255;
}
}
return (color1 / 9 & 255) << 16 | (color2 / 9 & 255) << 8 | color3 / 9 & 255;
}
BlockLeaves
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) {
...
} else {
// Using that added and shared method:
return ColorizerFoliage.calculateAverageColorMultiplier(par1IBlockAccess, par2, par4);
}
}
BlockGrass
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) {
// Using that added and shared method:
return ColorizerGrass.calculateAverageColorMultiplier(par1IBlockAccess, par2, par4);
}
BlockVine
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) {
return ColorizerFoliage.calculateAverageColorMultiplier(par1IBlockAccess, par2, par4);
}
BlockTallGrass
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) {
int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
return var5 == 0 ? 16777215 : ColorizerGrass.calculateAverageColorMultiplier(par1IBlockAccess, par2, par4);
}
Tested on 1.4.7 and seems to work. I'll attach a screenshot of the results 'fixed-coloring.png': note the rows of grass/ferns, and the vines on the tree at right side.
I think this is because the Anvil format does not store the calculated Temperature and Rainfall values when the world is generated, thus the game has to go with the "average" values for the biome stored in the world file.
Perhaps what is needed is a revised version of Anvil that stores the temperature and rainfall, and when upgrading chunks, recalculate those values and store them. This would restore the original smooth transitions.
No need to save the averages. But what would be an improvement giving the same end result but less CPU load, is to calculate the average at chunk load time and keep the results in memory. It would slow the loading a tiny bit, but on the other hand it would speed up the rendering part.
That idea has a minor hiccup in it, though. It would need to delay the average calculations from the chunk load time to a point where all the neighbor chunks are also loaded (as it needs the data from neighbor chunks for some blocks). Nothing difficult really, but I don't recall to have seen such existing mechanism in Minecraft yet, so it is an extra step to design first.
Ferns and vines not fading is only half the problem (which I didn't ever notice BTW), the "bug" reported here was about all biome transitions, including grass, leaves etc. Of course I'm using snapshot 16w07b, as you can see in the pic I uplodad, the one with the plains/savanna transition: the fade is still really short, I can just see 2 intermediate colors between the plains' green and the savanna's brown.
It's not really a bug so there's no expected result. Colors just change too abruptly since Anvil was introduced, and if it's marked as fixed I expect it to be fixed.
Ok. I think the shorter fading is probably in order to reduce CPU loading (assuming they haven't implement any of the optimizations discussed in comments earlier), thus not considered a bug, but more or less intended. (Since Mojang doesn't bother to communicate about the choices/changes/solutions, we can only guess.) Since they did fix the ferns and stuff, I'd assume they did read about the shorter fading range, too, but decided not to improve it (and my fixes didn't touch the ranges, either).
The underlying issue is that pre-Anvil the foliage color was calculated by values of temperature and rainfall per block, and the biome was calculated based on those values. Since Anvil, those values have been thrown out, and thus the data necessary for a long, smooth transition between biomes no longer exists.
Edit: Just tested with 16w07b
The biome coloration is still quite flat. Pre-Anvil there would be fluctuations in color, based on the mentioned temperature and rainfall values.
setting your graphics to "fast" will fix this problem. Although you wont have the gradation.