Search Unity

Question Render multiple .png files to a single texture

Discussion in 'Scripting' started by varrav, Jan 9, 2023.

  1. varrav

    varrav

    Joined:
    Mar 6, 2020
    Posts:
    3
    Hi!

    Is there a way to render(draw) multiple png files (with different resolution and transparency, to proper coordinates) to a single texture (or may be something else) which further I can apply to Image.sprite and show the result on the screen?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    You can do this with render textures.

    If you'd like an example, here's what I did for a lotto scratcher:

     
    angrypenguin likes this.
  3. varrav

    varrav

    Joined:
    Mar 6, 2020
    Posts:
    3
    Could you please explain how you did it: which classes and methods were used? Is there any source code to look at?
    Before I used native android and libGDX for such things and in every case there were a clear api to draw png into some image (Canvas.drawBitmap() in android and Pixmap.drawPixmap() in libGDX), is there a similar api in Unity?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    You should look in the description for that video. You'll be AMAZED!
     
    angrypenguin likes this.
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,004
    You may be looking for Graphics.Blit. Though Unity has several low level APIs like the GL class.
     
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    You can also read your images into Texture objects, then Get and Set pixels. This is slow, but I do it for occasional Editor stuff anyway because it can keep the code simpler.
     
    Kurt-Dekker and Bunny83 like this.
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,004
    Right, though you can't really re-scale the individual images directly. Though I made a bilinear sampler over here if you need one. It can up or down scale an image with bilinear filtering and would also crop the image from the center if the aspect ratio does not fit. So it does not distort the image. The TextureTools also have a letterbox version which would simply add bars either at the sides or at the top and bottom in case the target size does not have the same aspect ratio than the source.
     
    angrypenguin likes this.
  8. varrav

    varrav

    Joined:
    Mar 6, 2020
    Posts:
    3
    Hi! Seems Graphics.Blit() more or less suitable, but instead of transparency I see green pixels in the resulting image.
    I do:
    Code (CSharp):
    1.  
    2. //resulting texture
    3. Texture2D texture = new Texture2D(960, 640, TextureFormat.ARGB32, false);
    4.  
    5. for(LevelItem item in levelItems){
    6.     //each item data is a png file with transparency
    7.     byte[] itemImageRawData = System.IO.File.ReadAllBytes(item.fileName);
    8.     Texture2D texItem = new Texture2D(2, 2, TextureFormat.ARGB32, false);
    9.     bool itemLoaded = ImageConversion.LoadImage(texItem, itemImageRawData);//load item texture
    10.     RenderTexture rtItem = new RenderTexture(texItem.width, texItem.height, 32, RenderTextureFormat.ARGB32);
    11.    
    12.     Graphics.Blit(texItem, rtItem);//draw each item to render texture
    13.  
    14.     rect = new Rect(0, 0, texItem.width, texItem.height);
    15.     texture.ReadPixels(rect, item.x, item.y);//draw each item to resulting texture at the proper location
    16. }
    17.  
    18. texture.Apply();
    19. var bgSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
    20. GetComponent<Image>().sprite = bgSprite;//put resulting sprite into Canvas
    21.