Search Issue Tracker
By Design
Votes
1
Found in
2018.4
2019.4
2020.3
2020.3.2f1
2021.1
2021.2
Issue ID
1329222
Regression
No
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
Comments (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 ++
Add comment
All about bugs
View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.
Latest issues
- Warnings thrown when computing Positions in a 2D BlendTree are not helpful to the user
- Warnings thrown when adjusting Time Scale to Homogenous Speed in a BlendTree are not helpful to the user
- Crash on __pthread_kill when opening a specific project
- Animator States disappear when opening their Context Menus right after Pasting them
- "NullReferenceException" is thrown when rapidly expanding and collapsing the folders in the VFX Graph Node creation menu
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).