Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by blaize26 · Dec 15, 2021 at 07:36 PM · texture2dexportalpha-channelsetpixels

SetPixels and ExportToPNG - Alpha value missing?,

Hello. I made a script to generate a random map and then export it into PNG format. Everything works fine except for one sprite with alpha values that apparently get lost somewhere. alt text

(Left is scene view, right is the exported PNG). Code I'm working with:

     void ExportToPNG()
     {    
         int ppu = 16;
         //size x ppu 100x16
         Texture2D tex = new Texture2D(width*ppu, height*ppu, TextureFormat.RGBA32, false);


     
         [removed bits of the big loop code here unrelated to the issue]


         //drawing boss icon on the PNG file
         tex.SetPixels((x*ppu)-8, (y*ppu)-8, ppu*2, ppu*2, GetCurrentSprite(_tilemaps[tm].GetSprite(new Vector3Int(x,y,0))).GetPixels());
 
         tex.Apply();               
         byte[] bytes = tex.EncodeToPNG();
         File.WriteAllBytes(Application.dataPath + "/../map_"+mapsGenerated+".png", bytes);
         mapsGenerated++;        
         //clearMap();
     }
 
         
     Texture2D GetCurrentSprite(Sprite sprite)
     {
         Color[] pixels = sprite.texture.GetPixels((int)sprite.textureRect.x, (int)sprite.textureRect.y, (int)sprite.textureRect.width, (int)sprite.textureRect.height);
         Texture2D text = new Texture2D((int)sprite.textureRect.width, (int)sprite.textureRect.height, TextureFormat.RGBA32, false);
         text.SetPixels(pixels);
         text.Apply();        
         return text;
     }



I've been stuck here for a while now and can't seem to find a solution or what's actually going wrong. Any ideas? Thanks in advance.

,

help.png (220.7 kB)
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Eno-Khaon · Dec 16, 2021 at 04:28 AM 0
Share

For clarification, at what point is the alpha channel lost? For example, is it when the exported/written PNG file is reimported into Unity?

avatar image metalted · Dec 16, 2021 at 07:30 AM 0
Share

Might be better to add some intermediate steps instead of doing everything in one go. One thing i would do is to actually log the Color[] pixels to see if the alpha channel of the pixels is correct. You could also use GetPixel instead of GetPixels in a loop, so you can check every pixel yourself. That way you can check if the pixel you are reading is an alpha pixel and set the value you need accordingly.

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Dec 16, 2021 at 02:36 PM

I think you have the wrong idea about what you're doing here. You have this line of code and comment:

  //drawing boss icon on the PNG file
  tex.SetPixels((x*ppu)-8, (y*ppu)-8, ppu*2, ppu*2, GetCurrentSprite(_tilemaps[tm].GetSprite(new Vector3Int(x,y,0))).GetPixels());

This does not "draw" your texture onto the other texture. This replaces the pixels in the rectangular region in target image with the pixels of your sprite texture. It does not "draw" the image onto the background. This sounds like you want to do the same that was asked over here.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image blaize26 · Dec 16, 2021 at 02:49 PM 0
Share

Ah! it seems in my $$anonymous$$d I expected it to draw 'invisible' pixels as long as they had an alpha value of 0. I've now fixed it by doing a single SetPixel at a time and skipping the Alpha = 0 pixels. Thanks!

avatar image Bunny83 blaize26 · Dec 16, 2021 at 02:57 PM 0
Share

While you can use several SetPixel calls, it's quite inefficient. It probably doesn't matter for your usecase. However combining the pixels manually inside a Color array is generally way faster than calling SetPixel in a loop.

avatar image
0

Answer by blaize26 · Dec 16, 2021 at 12:21 PM

@Eno-Khaon @metalted It seems to go missing during the "GetCurrentSprite" call. I've tried debugging it as such:

     Texture2D GetCurrentSprite(Sprite sprite)
     {
         Color[] pixels = sprite.texture.GetPixels((int)sprite.textureRect.x, (int)sprite.textureRect.y, (int)sprite.textureRect.width, (int)sprite.textureRect.height);
          //the troubled icon is the only 32x32 sprite
         if(sprite.textureRect.width==32)
         {
             for(int p=0;p<pixels.Length/2;p++)
             {
                 pixels[p] = new Color(0f, 0f, 0f, 0f);
             }
         }
         Texture2D text = new Texture2D((int)sprite.textureRect.width, (int)sprite.textureRect.height, TextureFormat.RGBA32, false);
         text.SetPixels(pixels);
         text.Apply();        
         return text;
     }

result: alt text

new Color(1f, 1f, 1f, 0) returns black as well, while new Color(1f, 1f, 1f, 1f) returns white (as it should). alt text

Basicly ignoring the alpha no matter what on the exported PNG.


pic1.png (40.0 kB)
pic2.png (44.6 kB)
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image metalted · Dec 16, 2021 at 01:39 PM 0
Share

Hmm thats weird, so basically you cant make an alpha channel even if you set it directly. Don't really understand why thats happening. Maybe you can try using another Color struct like Color32? Think that supports alpha as well, right?

avatar image blaize26 metalted · Dec 16, 2021 at 02:02 PM 0
Share

Exact same behavior with Color32 as well. I'm really stumped by this. I've also tried Color.clear, still get black and no transparency.

avatar image metalted blaize26 · Dec 16, 2021 at 03:06 PM 0
Share

What instead of tex.SetPixels((x*ppu)-8, (y*ppu)-8, ppu*2, ppu*2, GetCurrentSprite(_tilemaps[tm].GetSprite(new Vector3Int(x,y,0))).GetPixels()); you try something like:

 Color[] bossPixels = GetCurrentSprite(_tilemaps[tm].GetSprite(new Vector3Int(x, y, 0))).GetPixels();
         int pixelIndex = 0;
         for(int i = x * ppu - 8, i < x * ppu + 8; i++)
         {
             for (int j = y * ppu - 8, j < y * ppu + 8; j++)
             {
                 Color pixelColor = bossPixels[pixelIndex];
                 if(pixelColor.a != 0f)
                 {
                     tex.SetPixel(i, j, pixelColor);
                 }
                 pixelIndex++;
             }
         }

As in, if the pixel in the sprite is alpha, don't set the pixel at all in the result. Not sure if this code works right, cause its kinda hard to test it myself and im not sure about the pixel order, so you might end up with a weird sprite. But at least you can test if it helps with the transparancy.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

141 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Baking decals into a texture 3 Answers

Texture2D SetPixels/Apply changes not permanent. 2 Answers

SetPixels32 On A Sprite In Texture2D Atlas 0 Answers

Drawing a solid circle onto texture 2 Answers

Setpixels creates gradient texture instead of raw colored pixels 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges