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
- var VisionOSEDRHeadromm has a comma instead of a dot when building with Metal Rendering App Mode and local OS localization is set to German
- IAP Catalog remove product “x” and add product “+” buttons are not consistent with other remove and add buttons in the Editor
- Performance issues in Play Mode when quickly hovering the mouse cursor over Hierarchy GameObjects
- Frame Debugger displays incorrect output when FidelityFX Super Resolution or Spatial-Temporal Upscaler is used with Temporal Anti-aliasing or Subpixel Morphological Anti-aliasing
- The layout system is failing to correctly calculate or apply the height of the Japanese fallback font when the primary English font's metrics are used
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).