• 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
4
Question by ackley14 · Jul 17, 2015 at 12:44 PM · imagemergecombining

Merge multiple png images one on top of the other?

Im working on a custom item system for a project and i was wondering if there's a way to take several base PNG files, (or any alpha containing picture file) and stack them on eachother one at a time, to create a custom new image for use in the game at runtime

basically the idea is, the user selects various parts for their item (maybe a gem, a tool head and a tool handle or something like that) then the a new item image is created based on the stacked base images.

is anything like this doable?

Comment
Add comment
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

3 Replies

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

Answer by Bunny83 · Jul 18, 2015 at 02:53 AM

Well, alpha blending in the sense of (srcA, oneMinusSrcA) is pretty easy. Just grab the pixel data using GetPixels() of both images (I assume they have the same resolution?). All you have to do is multiply the color of your top image by it's own alpha value. Same for the bottom image. To combine the two colors, just multiply the bottom color by (1.0 - alpha value of top color) and add the colors together. Next we have to calculate the alpha value of the resulting color. It's simply (T.a + (1.0-T.a)*B.a). Finally we divide the color itself by the new alpha value

It's well described over here.

Something like that:

 // C#
 using UnityEngine;
 
 public static class ImageHelpers
 {
     public static Texture2D AlphaBlend(this Texture2D aBottom, Texture2D aTop)
     {
         if (aBottom.width != aTop.width || aBottom.height != aTop.height)
             throw new System.InvalidOperationException("AlphaBlend only works with two equal sized images");
         var bData = aBottom.GetPixels();
         var tData = aTop.GetPixels();
         int count = bData.Length;
         var rData = new Color[count];
         for(int i = 0; i < count; i++)
         {
             Color B = bData[i];
             Color T = tData[i];
             float srcF = T.a;
             float destF = 1f - T.a;
             float alpha = srcF + destF * B.a;
             Color R = (T * srcF + B * B.a * destF)/alpha;
             R.a = alpha;
             rData[i] = R;
         }
         var res = new Texture2D(aTop.width, aTop.height);
         res.SetPixels(rData);
         res.Apply();
         return res;
     }
 }

If you add this class to your project you can simply create a new texture out of two like this:

 // C#
 Texture2D bottom;
 Texture2D top;
 
 Texture2D combined = bottom.AlphaBlend(top);

 // UnityScript
 var bottom : Texture2D;
 var top : Texture2D;
 
 var combined = bottom.AlphaBlend(top);


Keep in mind that you have to make the textures readable in the texture importer by switching to the texture type "advanced". If you don't do that, GetPixels will fail.

Since GetPixels also allows you to specify a region of the image you could combine only parts of the image, but it makes the for loop quite a bit more complicated. You also have to pass more parameters to the method to specify the source / target rectangle.

Comment
Add comment · Show 3 · 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 Bunny83 · Jul 18, 2015 at 03:11 AM 0
Share

Just some more information:
Alpha blending as it's done on the GPU works similar. Here's a link to the OpenGL wiki about blending. There are several different ways how to combine two images. However in most cases you want plain alpha blending like in my example.

avatar image ackley14 · Jul 18, 2015 at 10:42 PM 0
Share

this was insainly informative, thank you so much! i guarentee i'll be refrencing this in the future!!! thanks again for the very helpful answer!

avatar image OlliIllustrator · Jan 11, 2018 at 05:44 PM 0
Share

Thank you, your answer helps me a lot:-)

avatar image
1

Answer by Dave-Carlile · Jul 17, 2015 at 12:48 PM

You can do this on the GPU using a shader to composite multiple images. Supply each one as a texture and and use a render target to run the shader and combine them into a new texture. You can look at the source code for Unity's Image Effects to get ideas for how to do this. Even though those are operating on full screen images the same basic principals apply.

Another way is to do this on the CPU. If the images are small enough and you don't have huge numbers of them this would be viable as well. Load the images as textures, use GetPixels to get the pixel data, run through image A, get the corresponding pixel from Image B, combine them how you want using alpha, output to Image C. Next use Image C as input to the next round, repeat. If you have a limited number of input images you could combine them all at once rather than two at a time.

Comment
Add comment · Show 3 · 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 ackley14 · Jul 17, 2015 at 12:52 PM 0
Share

I'd definitely prefer the GetPixels method simply due to the fact that i have literally no knowledge of the shaders api or whats involved in that haha. i'll have to give that a go, i saw some source examples of something like that a little while ago. so basically, it would take A (i.e. the bottom image) and layer the pixels of B (the next image) over top? where alpha pixels would be "ignored" so to speak? as if you were placing painted glass one on top of the other?

avatar image ackley14 · Jul 17, 2015 at 12:55 PM 0
Share

i guess to better explain my new question, if the B image had alpha, would that alpha overwrite A's pixles? say at (15,15) A had a color, but B had alpha. would you see the A pixel or B pixel?

avatar image Dave-Carlile · Jul 17, 2015 at 06:24 PM 0
Share

It depends on what you want. You can either do an alpha mask sort of thing where alpha is either 0 or 1. If image B is put on top of Image A, any pixel in B with alpha = 1 would overwrite the corresponding pixel in A. This would be the fastest to do on the CPU since there's no math involved.

The other option is to do the actual alpha blend between the pixels. If your B alpha is still just 0 or 1 you end up in the same place as the first scenario. But if it's between 0 or 1 you get a blending of the two so A still shows through partially.

You can add the colors or multiply them or combine them in any other way you want. I would start getting the first scenario to work, then if you need your top image to be partially transparent go read about alpha blending or image compositing.

avatar image
0

Answer by vogles · Jul 17, 2015 at 07:03 PM

Image composition is a complicated subject. Yes, you can write shaders or Get/SetPixels. But if you're asking how to do it either of those ways, then it's probably too advanced for you, atm.

I'm assuming this is a 2D game. The easiest approach would be to simply have multiple GameObjects that represent the different images and place them in the correct locations. When Unity renders the objects they will get composited for you into what looks like a single image.

If you really really want to go the DIY image composition route, I would still recommend starting off with the multiple GameObject route, while you learn and build your shaders or scripts that will composite stuff the way you want.

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 Dave-Carlile · Jul 17, 2015 at 07:37 PM 0
Share

Yes. Simple is often the best approach. This can be a bit of a headache to deal with, but definitely another good option.

avatar image ackley14 · Jul 18, 2015 at 12:42 AM 1
Share

well this way could definitely work as well, however im a VERY quick study, i went from basically no knowledge of unity to being very skilled with javascript and unity's internal systems in just about 3 months of being self taught. it ultimately comes down to the fact that if i can find the information, and i can do testing, then i can figure it out haha. i'll leave this option as a last resort but if i do have to go this rout, is there a way to order the hierarchy on runtime? or do you just have to make sure you set the various objects's parents in the right order?

avatar image Dave-Carlile · Jul 18, 2015 at 01:22 AM 1
Share

You can use Transform.SetSiblingIndex, SetAsFirstSibling, and SetAsLastSibling to change the hierarchy order.

You can also use sprite ordering if you're using sprites.

avatar image ackley14 · Jul 18, 2015 at 01:25 AM 0
Share

awesome thanks the both of you. i've decided that because i know for a fact each item will have a very specific amount of pieces, therefore a specific ammount of images, that i can use a prefab that is instantiated and setup accordingly once at runtime! :D thanks for the super helpful answers!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

6 People are following this question.

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

Related Questions

Is there a way to put images on each side of a cube,so that only clickable areas of the cube would be those images ? 0 Answers

How to load an image from file path? 1 Answer

Image becomes distorted when running on IOS 2 Answers

[4.6] How can I make children images not stretch with the parents? where to place anchors? 1 Answer

How to grab POST image data from WWWForm on server? 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