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
-
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
- Fixing Message Loss in UMPE During Domain Reload
- The Editor freezes when ScheduleReadOnly of IJobParallelForTransform with dependency is used
- Text is truncated in the Inspector when the display scale is set to 150%
- CancellationTokenSource(<timeout>) has incorrect cancellation status when used in WebGL Player
- VFX property value names are cut off when properties with 'Arc' are viewed in the VFX Blackboard
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).