Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to blend colors in a texture2D with surrounding texture2D based on pixel distance

Discussion in 'Getting Started' started by trevk84, Jul 14, 2023.

  1. trevk84

    trevk84

    Joined:
    Feb 8, 2016
    Posts:
    3
    upload_2023-7-14_9-59-53.png

    A picture is worth a thousand words, so here is my best effort thus far. I feel like this should be an easy one, but my brain is stuck down a wrong path and can't change. As you can see, I'm having difficulties blending the corners, where 4 colors need to be blended together. The blend can be radial or rectangular, as shown. Not concerned about performance at this point, just proof of concept.

    Here is the code to create the grid of sprites and texture2Ds:
    (I didn't include my BlendColors() function because it's no good)

    Code (CSharp):
    1.     public int textureSize = 16;
    2.     public Vector2Int coordinate;
    3.     private Vector2Int storedCoordinate = Vector2Int.one;
    4.  
    5.     private SpriteRenderer[] cells;
    6.     private Color[] cellColors;
    7.  
    8.     private void Start()
    9.     {
    10.         CreateGrid();
    11.     }
    12.  
    13.     private void Update()
    14.     {
    15.         if (storedCoordinate != coordinate)
    16.         {
    17.             coordinate.x = Mathf.Clamp(coordinate.x, 0, textureSize - 1);
    18.             coordinate.y = Mathf.Clamp(coordinate.y, 0, textureSize - 1);
    19.             storedCoordinate = coordinate;
    20.             Color[] pixels = cells[4].sprite.texture.GetPixels();
    21.             for (int y = 0, i = 0; y < textureSize; y++)
    22.             {
    23.                 for (int x = 0; x < textureSize; x++, i++)
    24.                 {
    25.                     if (x == coordinate.x && y == coordinate.y)
    26.                     {
    27.                         pixels[i] = BlendColors(coordinate);
    28.                     }
    29.                     else
    30.                     {
    31.                         pixels[i] = cellColors[4];
    32.                     }
    33. //pixels[i] = BlendColors(coordinate); uncomment this to effect the entire cell
    34.                 }
    35.             }
    36.             cells[4].sprite.texture.SetPixels(pixels);
    37.             cells[4].sprite.texture.Apply();
    38.         }
    39.     }
    40.  
    41.     private void CreateGrid()
    42.     {
    43.         cells = new SpriteRenderer[9];
    44.         cellColors = new Color[cells.Length];
    45.  
    46.         for (int y = -1, i = 0; y <= 1; y++)
    47.         {
    48.             for (int x = -1; x <= 1; x++, i++)
    49.             {
    50.                 Vector2 position = new Vector2(x, y) * 1;
    51.                 cellColors[i] = ReturnCellColor(i);
    52.                 CreateCell(i, position, cellColors[i]);
    53.             }
    54.         }
    55.     }
    56.  
    57.     private void CreateCell(int index, Vector2 coordinate, Color color)
    58.     {
    59.         GameObject cell = new GameObject("Cell " + (index + 1));
    60.         cell.transform.position = new Vector3(coordinate.x, coordinate.y, -9.9f);
    61.  
    62.         Texture2D cellTexture = new Texture2D(textureSize, textureSize, TextureFormat.RGB24, true);
    63.         cellTexture.wrapMode = TextureWrapMode.Clamp;
    64.         cellTexture.filterMode = FilterMode.Point;
    65.         Color[] pixels = cellTexture.GetPixels();
    66.         for (int i = 0; i < pixels.Length; i++)
    67.         {
    68.             pixels[i] = color;
    69.         }
    70.         cellTexture.SetPixels(pixels);
    71.         cellTexture.Apply();
    72.  
    73.         cells[index] = cell.AddComponent<SpriteRenderer>();
    74.         cells[index].sprite = Sprite.Create(cellTexture, new Rect(0, 0, textureSize, textureSize), Vector2.zero, textureSize);
    75.     }
    76.  
    77.     private Color ReturnCellColor(int i)
    78.     {
    79.         switch (i)
    80.         {
    81.             case 0:
    82.                 return new Color(1f, 0f, 0f, 1f);
    83.             case 1:
    84.                 return new Color(0f, 1f, 0f, 1f);
    85.             case 2:
    86.                 return new Color(0f, 0f, 1f, 1f);
    87.             case 3:
    88.                 return new Color(1f, 1f, 0f, 1f);
    89.             case 4:
    90.                 return new Color(0f, 1f, 1f, 1f);
    91.             case 5:
    92.                 return new Color(1f, 0f, 1f, 1f);
    93.             case 6:
    94.                 return new Color(1f, 1f, 1f, 1f);
    95.             case 7:
    96.                 return new Color(1f, 0.5f, 0f, 1f);
    97.             case 8:
    98.                 return new Color(0f, 0f, 0f, 1f);
    99.         }
    100.         return new Color(Random.value, Random.value, Random.value, 1f);
    101.     }
    102.  
    103.     private Color BlendColors(Vector2Int coordinate)
    104.     {
    105.         float blend = 0.25f;
    106.         int blendTiles = Mathf.CeilToInt(textureSize * blend);//the amount of pixels on the edge of texture that will blend to surrounding texture's color
    107.      
    108.         return blendColor;
    109.     }
     
  2. AngryProgrammer

    AngryProgrammer

    Joined:
    Jun 4, 2019
    Posts:
    431
    To blend two colors you can use the below example. Should give better results.
    Code (CSharp):
    1. Color blendedColor = Color.Lerp(color1, color2, blendFactor);
     
  3. trevk84

    trevk84

    Joined:
    Feb 8, 2016
    Posts:
    3
    That's what I use for the edges, and it works well (I only want the outer 4 pixels to blend, so I know it's not going to be that smooth), but I'm having trouble blending the corners because there you have to blend 4 different colors together