RandomMcSomethin / fallingleaves

MIT License
43 stars 20 forks source link

Resource Packs can change texture color #15

Closed Fourmisain closed 3 years ago

Fourmisain commented 3 years ago

I originally thought only OptiFine would cause issues with changing leaf textures and therefore colors (https://github.com/RandomMcSomethin/fallingleaves/issues/8), but as it turns out, Resource Packs can do that just as well.

The same example A Little Taste of Jerm V2.5 changes the default color of birch leaves to orange.

This is done by coloring birch_leaves.png orange and this apparently makes the texture unaffected by block colors. On the other hand there's e.g. acacia_leaves.png which is grayscale and is affected by block colors.

The files themselves have no apparent format distinction, both are 32 bit RGB(A) PNG, so it looks like Minecraft does some sort of grayscale test to decide to color textures or not.

Fourmisain commented 3 years ago

it looks like Minecraft does some sort of grayscale test to decide to color textures or not

Did some testing, apparently every gray pixel is being colored, some colors are just more resistant to change.

tint

The particle texture uses full red, full blue and full green, the blue is most affected in this example. (I'm assuming the coloring/tinting/color blending for particles is the exact same as for block textures.)

Looking at our current code,

https://github.com/RandomMcSomethin/fallingleaves/blob/9371048df3686a9b7e55b16c671fdcf7aa7d14ee/src/main/java/randommcsomethin/fallingleaves/util/LeafUtil.java#L43-L49

we probably need to add a test if a block's texture is changed by a resource pack, average its color and mix it with the block color.

Fourmisain commented 3 years ago

I wonder though how the coloring works, the nightshade leaves to the left have an average color of [r=155,g=108,b=4] and the particles's blue is also almost black, so it's not simply averaging the colors.

Colorpicking from the image, the particle's blue is [r=0,g=0,b=4], the green is [r=0,g=107,b=0] and the red is [r=153,g=0,b=0], so it seems to clamp the values component-wise?

Fourmisain commented 3 years ago

I ran some (ten thousands) simulations using random clamping values on random 64*64 pixel arrays and if I didn't mess up the implementation, there's a bounded error between averaging the clamped colors (which may be true to the actual colors) and clamping the average color (which is much easier to calculate and most importantly, we only need to cache one value).

Here's the raw data:

norm: Maxnorm
norm(255, 255, 255) = 255.0
min absolute error: 0.042724609375
avg absolute error: 19.264097583007814
max absolute error: 32.684326171875
max relative error: 25.49720833485385%

norm: Taxicab
norm(255, 255, 255) = 765.0
min absolute error: 0.044921875
avg absolute error: 32.028016870117185
max absolute error: 93.837158203125
max relative error: 24.21967085949251%

norm: Euclid
norm(255, 255, 255) = 441.6729559300637
min absolute error: 0.0434282185909451
avg absolute error: 22.48376075064385
max absolute error: 52.09451466613003
max relative error: 23.802066287674347%

The used norm doesn't seem to make any difference, so looking at the Maxnorm is easiest.

It's saying that the maximum absolute error is around 32 - so each color component is at most 32 away from it's "true" value. The max relative error is 25%, so you may say that clamping the average color is about 25% inaccurate compared to averaging the clamped values.

That may be close enough to justify using the "easy" method of clamping the average color since the falling leaf colors don't need to perfectly match the blocks they came from - they are also rendered full bright, which already is inaccurate to the real block colors.

Fourmisain commented 3 years ago

I don't think the values are clamped, I think they are simply multiplied (once brought into the 0-1 range).

What I currently don't understand is this:

colored almostunaffected

It really does look like the birch texture is unaffected by block colors, I colorpicked it once again, one pixel on the left side has RGB (147, 109, 39), while the same pixel on the right side has RGB (148, 114, 42). I extended it even further and it was RGB (142, 103, 38) vs RGB (146,111, 40) - there is a difference but why is it so small?

Fourmisain commented 3 years ago

Hm... lighted it up using glowstone under every block and now there really is no difference.

I can only concluce: The custom birch texture is unaffected by the block colors - the custom (grayscale) acacia texture is not.

Fourmisain commented 3 years ago

Ohh, I forgot, there literally is a function FoliageColors.getBirchColor() which returns a constant - birch is simply never affected by biome colors and it's the same without the resource pack.

That said, the falling leaf colors are off using multiplication - but only with the resource pack mult

Fourmisain commented 3 years ago

edit2: What I found here was because of a custom birch_leaves.json that had "parent":"block/leaves_cross_birch_new" and leaves_cross_birch_new.json had "parent": "block/block",, which I think effectively sets the tintindex to -1.


Okay, I found something weird.

Custom birch leaves textures are actually never colored! not colored in A Little Taste of Jerm V2.5.

Switching birch_leaves.png with the gray scale acacia_leaves.png gives this: interesting

And even more interesting: placing the original Vanilla birch_leaves.png (which is also grayscale) inside a this resource pack shows gray leaves as well!

This means that at least this very issue for Birch Leaves can simply be fixed by only using the texture color if it was overwritten by a resource pack. (edit2: Yes, but actually no.)

The thing is that I don't yet know which leaves this applies to.

edit: looking inside BlockColors, it seems that only birch and spruce are affected by this. I'm not sure if there's any mods that have leaves that are colored by biome colors.

Fourmisain commented 3 years ago

I got it!

Coloring works like this: Every quad has a tintIndex (named colorIndex inside BakedQuad) which is either -1 or... not -1. It is really a boolean which tells the renderer to multiply the texture color with the block color.

The issue with resource packs and also the inaccurate falling leaf color (brightness) in general was that we previously only either read the block color or the texture color.

Instead we should always read both (if the texture is grayscale, we still need to find the brightness of it) and multiply the values together if the tintIndex of e.g. the bottom quad isn't -1 (if BakedQuad.hasColor() is true).

Here's a comparison:

Before

before_withouttexturepack before_withtexturepack

After

after_withouttexturepack after_withtexturepack

Fourmisain commented 3 years ago

Ahhh... it's not perfect. A lot of BYG leaves now have wrong colors aww

Fourmisain commented 3 years ago

Okay, there's two issues:

Nightshade Leaves are actually not supposed to be biome colored at all! I took the image above using OptiFine and I thought I disabled all options that would affect this (everything under "Quality" is disabled) - turns out, "Swamp Colors" under "Details" should actually be on.

While testing I also noticed that the "Custom Colors" quality option also breaks the leaf colors...

Fourmisain commented 3 years ago

Oops, forgot to close this.

https://github.com/RandomMcSomethin/fallingleaves/commit/1a81cfc64e39aefb1111e6c716498ef321bb43a4