I have 2 sprite on UI using Image Component. They are monocolor and transparent (black and transparent or red and transparent…). I want to highlight the intersection and I want to know how much (percentage) the intersection represents of the original image (it can be compared to one sprite or the other)
For example:
I have a “bear” image and a “circle” image. The red part is the highlight of the intersection. It represents (e.g.) 2% of the bear and 8% of the circle.
I started trying with texture2D.GetPixels() and create another texture and compare them but this is so costy to CPU. I believe it could be done on GPU but I don’t know where to start.
I need to know the percentage representation of the intersection, I do not want just to highlight the intersection area.
Ok. Since I need to calculate only on one frame (not every frame) it can be done on CPU without so much cost. In my case I only have “colored” pixels and “transparent” pixels which make things easier for me. If anyone wants to know how I did it, here’s my code:
[SerializeField] private Image m_Control;
[SerializeField] private Image m_Player;
private IEnumerator Validate()
{
Texture2D controlTexture = m_Control.sprite.texture;
Texture2D playerTexture = m_Player.sprite.texture;
int totalPixels = 0;
int pixelsRight = 0;
int pixelsWrong = 0;
float startTime = Time.time;
for(int x = 0; x < m_Control.sprite.texture.width; x++)
{
for (int y = 0; y < m_Control.sprite.texture.width; y++)
{
Color controlPixel = controlTexture.GetPixel(x, y);
Color playerPixel = playerTexture.GetPixel(x, y);
if(controlPixel.a - playerPixel.a < 0.1f)
{
pixelsRight++;
}
else
{
pixelsWrong++;
}
totalPixels++;
}
//just to not lag for the user with low processing power
if(x % 100 == 0)
{
yield return null;
}
}
Debug.Log($"Total time calculating: {Time.time - startTime}");
Debug.Log($"Total pixels right {pixelsRight}");
Debug.Log($"Total pixels wrong {pixelsWrong}");
Debug.Log($"Total pixels {totalPixels}");
Debug.Log($"Match: {(pixelsRight / (float)totalPixels) * 100.0f}%");
}
With a 500x650 pixels sprite it took 0.22 seconds on my mac to calculate. Need further test on mobile.
but this only works if your textures are the same size, and centered on the same point, this wont work if you move the objects in the scene, scaled differently, or different canvas sizes
True indeed! But in my case it was easier to fix it onto level design than to make a robust code to cover all the possibilities. But the idea is the same. Apply some offset, some extra checks and it will probably do the trick.