SetPixel faster on mouse drag

Viewed 24

Hi I'm creating a cleaning game but encountered a problem when I fast draw a straight line the line is broken but when I slow draw a straight line it works fine

enter image description here

Below is my code

private void Update()
{
     if (Input.GetMouseButton(0))
     {

         if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit))
         {
             Vector2 textureCoord = hit.textureCoord;

             int pixelX = (int)(textureCoord.x * _templateDirtMask.width);
             int pixelY = (int)(textureCoord.y * _templateDirtMask.height);

             Vector2Int paintPixelPosition = new Vector2Int(pixelX, pixelY);

             int paintPixelDistance = Mathf.Abs(paintPixelPosition.x - lastPaintPixelPosition.x) + Mathf.Abs(paintPixelPosition.y - lastPaintPixelPosition.y);
             int maxPaintDistance = 7;
             if (paintPixelDistance < maxPaintDistance)
             {
                 return;
             }
             lastPaintPixelPosition = paintPixelPosition;

             int pixelXOffset = pixelX - (_brush.width / 2);
             int pixelYOffset = pixelY - (_brush.height / 2);

                 for (int x = 0; x < _brush.width; x++)
                 {
                     for (int y = 0; y < _brush.height; y++) {
                         Color pixelDirt = _brush.GetPixel(x, y);
                         Color pixelDirtMask = _templateDirtMask.GetPixel(pixelXOffset + x, pixelYOffset + y);

                         float removedAmount = pixelDirtMask.g - (pixelDirtMask.g * pixelDirt.g);
                         dirtAmount -= removedAmount;

                         _templateDirtMask.SetPixel(
                             pixelXOffset + x, 
                             pixelYOffset + y, 
                             new Color(0, pixelDirtMask.g * pixelDirt.g, 0)
                         );
                     }
                 }


             _templateDirtMask.Apply();
         }
     }
 }
1 Answers

Start Paint, and using the pen, try draw circles as fast as you can then look at the result:

enter image description here

Obviously, you didn't draw such straight lines with such clean direction change.

So, how is Paint able to cope up with such huge delta changes?

Interpolation

Some pseudo code:

  • on mouse down
    • get current mouse position
    • if last mouse position has been set
      • draw all the positions between last to current
        • use Bresenham algorithm for instance
    • save current mouse position to last mouse position

You could/should make your algo aware about pen size, with some simple math you can figure out the necessary step in evaluating points in the interpolation.

And don't use SetPixel, keep a copy of the texture pixels with GetPixels32 that you'll update and then upload it all at once using SetPixels32.

Related