Sprite.Create Differences between Editor and Android

I have been struggling today between the differences in a programmatically generated sprite between the editor and a pushed android build. Below is the code to generate the sprite:

using UnityEngine;

public class RuntimeSprite : MonoBehaviour {

    public float updatePeriodSeconds = 0.5f;
    public int width = 256;
    public int height = 256;

    private SpriteRenderer ren;
    private float cameraWidthUnits;

    // Use this for initialization
    void Start()
    {
        ren = GetComponent<SpriteRenderer>();

        Vector3 leftScreenBoundWorld = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0));
        Vector3 rightScreenBoundWorld = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0));

        Vector3 screenWidthVector = rightScreenBoundWorld - leftScreenBoundWorld;

        cameraWidthUnits = screenWidthVector.x;

        width = (int)(cameraWidthUnits * 8.0f);

        Texture2D tex = new Texture2D(width, height);
        tex.filterMode = FilterMode.Point;
        GenerateTexture(ref tex);
        ren.sprite = Sprite.Create(tex,
            new Rect(0, 0, width, height),
            new Vector2(0.5f, 0.5f), 8f);
    }

    private void GenerateTexture(ref Texture2D tex)
    {
        for (int x = 0; x < width; x++)
        {
            for(int y = 0; y < height; y++)
            {
                Color color = CalculateColor(x, y);               
                tex.SetPixel(x, y, color);
            }
        }

        tex.Apply();
    }

}

This code in the editor generates the following sprite as I would expect in my scene (The generated sprite is the vertical white, black, and red lines. The other sprite is a normal static sprite from a png at 8 pixels per unit): 125115-editorspritesnap.png

When I push the build to my Android device, not only are my pixels per unit off, but my sprite colors also change. Here you can see the results.125116-androidspritesnap.png

Any idea what would cause this? I have verified via debugging on the device that the correct colors are being set on the texture.



UPDATE:
So I was able to get the texture to render on Android correctly if I make it 2x the size and double the ppu to 16. The issue here is that I’m generating this sprite every ~0.1 seconds to sample some noise, and doing this for a sprite this large is too expensive of an operation.

This makes me think the issue is some sort of auto compression happening on my Android device. Although when I print my Texture2d’s format on my device, it displays as RGB32,



UPDATE 2:

I found a work around. Accepted answer posted below.

If anyone is interested I have found a work around for this.

Instead of programmatically creating the sprite and texture, I created an empty texture in the editor which will be large enough for my needs, and then programmatically modify the texture. In order to make this work, change the sprite’s settings to the desired values you want (pixels per unit, filter type, and compression to uncompressed). Under “Advanced” you must check the “Read/Write” box.

Then at runtime, simply modify the sprite’s texture via SetPixel and then when you are done, call texture.Apply(). This allowed the sprite to appear at the correct ppu without compression, as I desire. Code is below:

 using UnityEngine;
 
 public class RuntimeSprite : MonoBehaviour {
 
     public float updatePeriodSeconds = 0.5f;
     public int width = 256;
     public int height = 256;
 
     private SpriteRenderer ren;
     private float accumulatedDeltaT;
 
     // Use this for initialization
     void Start()
     {
         ren = GetComponent<SpriteRenderer>();
 
         width = ren.sprite.texture.width;
         height = ren.sprite.texture.height;

         accumulatedDeltaT  = 0f;
     }
 
     private void Update()
     {
         accumulatedDeltaT += Time.deltaTime;
         if (accumulatedDeltaT >= updatePeriodSeconds)
         {
              accumulatedDeltaT = 0;
              Texture2D tex = ren.sprite.texture;
           
              GenerateTexture(ref tex);
         }
     }

     private void GenerateTexture(ref Texture2D tex)
     {
         for (int x = 0; x < width; x++)
         {
             for(int y = 0; y < height; y++)
             {
                 Color color = CalculateColor(x, y);               
                 tex.SetPixel(x, y, color);
             }
         }
 
         tex.Apply();
     }
 
 }