Drawing performance issues. Color32.op_lmplicit() very slow

I try to paint by texture2d and get very poor performance, especially when trying to use a brush texture

 public void PenBrush(Vector2 world_point)
     {
         Vector2 pixelPos = WorldToPixelCoordinates(world_point);
         currentColors = drawableTexture.GetPixels32();
         if (previousDragPosition == Vector2.zero)
             MarkPixelsToColour(pixelPos, PenWidth, PenColour);
         else
             ColourBetween(previousDragPosition, pixelPos, PenWidth, PenColour);
         ApplyMarkedPixelChanges();
         previousDragPosition = pixelPos;
     }
public void MarkPixelsToColour(Vector2 center_pixel, int pen_thickness, Color color_of_pen)
    {
       
        int center_x = (int)center_pixel.x;
        int center_y = (int)center_pixel.y;

        for (int x = center_x - pen_thickness; x <= center_x + pen_thickness; x++)
        {
            if (x >= drawableSpriteWidth || x < 0)
                continue;
            for (int y = center_y - pen_thickness; y <= center_y + pen_thickness; y++)
                MarkPixelToChange(x, y, color_of_pen);
        }

        /*
        int center_x = (int)center_pixel.x;
        int center_y = (int)center_pixel.y;
        int drawableSpriteWidth = drawableSpriteWidth;
        pen_thickness = BrushTexture.width;
        int x = pen_thickness;
      
        while (x > 0)
        {
            x--;
            int y = pen_thickness;
            while (y > 0)
            {
                y--;
                if (x >= (int)drawableSprite.rect.width || x < 0)
                    continue;
                Color brushColor = BrushTexture.GetPixel(x, y);
                int array_pos = (y + center_y) * drawableSpriteWidth + (x + center_x);

                Color _endcolor = new Color();
                _endcolor.r = color_of_pen.r;
                _endcolor.g = color_of_pen.g;
                _endcolor.b = color_of_pen.b;
                _endcolor.a = 1;
                currentColors[array_pos] = Color.Lerp(currentColors[array_pos], _endcolor, brushColor.a > .9f ? 100 : brushColor.a / 5);

            }
        }
        */
    }
 public void MarkPixelToChange(int x, int y, Color color)
    {
        int array_pos = y * drawableSpriteWidth + x;
        if (array_pos > currentColors.Length || array_pos < 0)
            return;
        currentColors[array_pos] = color;
    }


    public void ApplyMarkedPixelChanges()
    {
        drawableTexture.SetPixels32(currentColors);
        drawableTexture.Apply();
    }

How can I improve my performance?

you are converting/casting Color to Color32?

but at least LoadRawTextureData used to be several times faster than using SetPixels stuff, but requires byte array

currentColors is Color32 array - currentColors[array_pos] = color;
thanks, I’ll see the option with LoadRawTextureData

this one has Color param,
MarkPixelToChange(int x, int y, Color color)

also math round can be optimize to something that doesnt use Mathf.

Not quite sure what I need to do with the color?

try Color32

public void MarkPixelToChange(int x, int y, Color32 color)

and for the other methods too

it’s still slow
https://gyazo.com/32ef0fbb6938d4f2e07f5da4e79a5c77

and as I understood this code is very slow:

currentColors[array_pos] = Color.Lerp(currentColors[array_pos], _endcolor, brushColor.a > .9f ? 100 : brushColor.a / 5);

or

currentColors[array_pos] = color;

now the color here is color32 but still slow

that also casts from Color to Color32 apparently,
divisions are slower than multiplications,
make you own lerp code and inline it (can be faster than using unitys),
could also precalculate those brushColor.a > .9f ? 100 : brushColor.a / 5 calculations outside loop if possible, since brush color wont change inside that loop?

I It would make sense if this codes were fast, but there is none of this and it is slow. And there is no transformation from color to color32. currentColors colors32 array and color is color32

currentColors[array_pos] = color;

but I don’t understand why replacing a value by key in an array is slow

You keep posting examples of using Color though so I’m not following exactly what you’re doing here but shouldn’t you be using Color32.Lerp to avoid the implicit conversion?

1 Like

currentColor contains the array of colors received via GetPixels32(), when the mouse moves over the texture, I get the position in the array - this is array_pos and I replace it with the color I need. And the fact is that if you comment out this particular line of code, and drive on the texture, then there are no problems in the profiler.

Who cares, I have attached a script. Just create a sprite renderer, add a 2D collider box and this script.

upd. Color32.Lerp helped well for this site, thanks!

7514681–926819–DrawingNew.zip (2.23 KB)