Source: Fireborne Blog

Fireborne Blog Making transparent GIFs with Unity and Photoshop

Hey guys, Jean here!I thought I'd take this opportunity to show how I made GIFs with transparent backgrounds from Unity. This is how we made the animated hero on the Fireborne front page for instance. It really makes it feel more polished that way! I think we'll use a lot more of those, they're pretty cool looking!So the process happens in two steps:Exporting transparent PNGs from UnityCreating a GIF from those PNGs in PhotoshopThe first part of the challenge is to be able to export a sequence of PNGs from Unity that have the correct transparency. There are several examples on how to capture PNGs from Unity, so I'll sort of start from there. You can find MY version of a simple PNG capture component here!To capture transparent screenshots, you need to do two things:Set the camera to clear the screen with a transparent color (typically transparent black).Make sure that your meshes properly write the alpha channel of the render texture that gets used to capture the screenshot.That second point is what most examples forget, or try to work around. In fact, if all you do is set the camera clear color to transparent black, you will often get this kind of PNG as a result:The reason this happens is because Unity doesn't really care about the alpha values it computes when it renders opaque meshes, and so it doesn't make any specific effort to write a meaningful value to the alpha channel. There is a very good reason for this: in most cases (rendering to the screen) it doesn't need to; all transparent geometry is always rendered after all opaque geometry, and even then, most transparent shaders don't care about the destination (screen) alpha value. So this isn't so much a bug as it is an optimization on their part.But in this case, of course, it matters! And so to work around that, we have no choice but to make a custom shader (i.e. material). The Greedling in the screenshot is using a Bump-Spec-Glow type of shader, so that's what I rewrote, or rather, modified.I grabbed the sources for the Bump-Spec-Glow built-in shader and added the following finalColor function:void writeAlpha(Input IN, SurfaceOutput o, inout fixed4 color){ // This is an opaque shader, force the output alpha to 1 color.a = 1.0f;}That's it! All I'm doing is writing 1 to the rasterized pixels. And now the captured PNGs looks like this:(Modified shader source here)Now that we have correct alpha in our PNGs, we need to capture a sequence of them.This happens by programmatically controlling the Mecanim Animator, single-stepping it (sort of) and capturing PNGs at each interval, incrementing the file numbers in the process. Later we'll import the individual files as a sequence.Controlling the Animator is entirely dependent on the Animation Controller that your character uses. Our Greedling has a pretty simple one, so the animation to capture is started by a Trigger, and then we wait until the Animator returns to its idle state. This will look different for you, but for me it was this little chunk of code: // Force the animator to restart that clip (really just a safety) and then record the animator. // This is the only way for us to be able to manually step the animator and capture images. animator.SetTrigger("PlayHandAttack0"); animator.StartRecording(0); // Wait for the anim to finish and return to Idle int stateHash = 0; do { yield return null; stateHash = animator.GetCurrentAnimatorStateInfo(0).nameHash; } while (stateHash == idleStateHash); do { yield return null; stateHash = animator.GetCurrentAnimatorStateInfo(0).nameHash; } while (stateHash != idleStateHash);But this needs to be wrapped inside calls to Animator.StartRecording() and Animator.StopRecording(). Using recording is the only way that you can manually frame-by-frame the Animator. You start recording, tell it to do things (in my case trigger the animation) and then stop recording.Then you're able to use Animator.StartPlayback() to put the Animator in a mode where you can manually set the animation time. That is done through the property Animator.playbackTime.So that's what I did: playback the animator, set the time manually, capture a PNG of the screen and then repeat the process. By the end I had a bunch of PNGs:(Full source file here)This is where Photoshop comes in. Seriously, Photoshop, CC '14 makes the rest of the process a breeze. I use the monthly subscription, and at only $10/month you can't beat it!Anyway, all you need to do once you have the sequence of images is open the first image in Photoshop and check the little "image sequence" checkbox in the Open File dialog. It will import all the images and show you a timeline of the resulting video.From here, you can crop, cut, paint, anything you want, it's just regular Photoshop, except you're editing a video... All *I* did was crop the image to not waste as much space, and so I ended up with this:Then I used the "Save for Web" feature (Ctrl+Shift+Alt+s), that's what creates the GIF and lets you make sure it has transparency.In the settings, I usually like to use no dithering for the main colors, and pattern or noise dithering for the transparency. With a fully opaque character it's not that important, but with those that have a bit more alpha, it can make a good difference in the final quality of the GIF.And that's it! Now you have a GIF with a transparent background.Jean!

Read full article »
Est. Annual Revenue
$100K-5.0M
Est. Employees
1-25
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100