By Design

Found in

Issue ID

Regression

## Color.gray is (0.502,0.502,0.502) instead of (0.5,0.5,0.5) when TextureFormat is set to ARGB32

-

How to reproduce:
1. Open the attached project "Color.zip"
2. Open Assets/Scenes/SampleScene
3. Enter Play Mode and press Space

Expected result: Console outputs "A gray pixel has been found"
Actual result: Console outputs "no more color"

Reproducible with: 2018.4.34f1, 2019.4.24f1, 2020.3.5f1, 2021.1.3f1, 2021.2.0a15

Notes: Setting TextureFormat to RGBAFloat solves the issue

1. Resolution Note:

This is by design because 8bit cannot exactly represent floating point value 0.5

The texture created is of type TextureFormat.ARGB32, this means we have 4 channels (RGBA) each using 8bit integers (so a total of 32 bits).
Given those 8bit, we have an effective integer range of between 0 and 255. To convert those values back/to floating point, you have to divide/multiply by 255.

So given the color gray (represented as 0.5 floating point), we end up with 127.5. This gets rounded to integer value 128 (There is an argument to floor to 127, but Unity using rounding, not flooring).
Converting back to float, we get 128/255 -> 0.50196 (or rounded 0.502, exactly the value you see).

There is literally no way to store 0.5 exactly in 8bit integer (127 would become 0.4980, 128 would be 0.5019).
Using for example TextureFormat.RGBAFloat will give you more accuracy that can exactly represent 0.5 (though remember that comparing floating point numbers is also tricky).

1. Geckoo

Apr 27, 2021 12:24

The Unity Color struct encodes colors as floating point values. So it could be again the old problem of checking floating point values for equality. However I don't understand why all other colors work well as expected. There is something wrong somewhere. Thank you for the explanation ++