Thursday, May 29, 2014

ZBrush Export to Unity 3D, Mesh + UV

ZBrush is a great tool in many ways. But there are other ways in which it is infuriating. It is mysterious about what it is doing in many cases, and the documentation on these mysteries is usually nothing more than a longer version of the text on the buttons and menus.

UV maps are one of the places where the data is slim, and the documentation tells you nothing about what's going on with the choices you make. It's like that Sherlock Holmes quote about it making perfect sense once you already know the answer.

On top of that, there's a lot of FUD about transferring data from ZBrush to Unity. Certainly there are other programs for which Unity makes the process more or less seamless, but ZBrush is perfectly capable of providing all the same data to Unity. It's just a matter of knowing the correct process. Which is difficult with ZBrush if you're just trying it on your own, because there are so many settings for which ZBrush doesn't show you directly the effects of your choices. You have to keep going back and forth between ZBrush and Unity--does this work? Does that work? What about that? On and on. And at each stage you're guessing, because you can't look at what comes through in Unity and say, "Oh, I see the problem. I need to just do -that-!" It's just a mishmash of unmatched data.

Well, I spent two solid days experimenting. Trying out different things, getting something to work, making sure I can do it twice in a row and have it work both times. Researching on the internet to see if someone else had a better way, and so on. You don't need to hear the whole litany--getting it done was my job, now here's the results for you to take advantage of so that you can get on with your project.

I'm using Unity 4.3.4f1 and ZBrush 4R6 for this. I'm covering just exporting the object mesh and its UV texture here. A normal map works similar to the UV texture--the key point being that it has to be vertically flipped to align with the mesh in Unity. If you're interested in another post that covers normal maps specifically, email me or leave a comment and I'll do it.

You've Got an Object in ZBrush

So your object is sculpted and polypainted in ZBrush, now you want to drop it into Unity.

First, you've got to convert the polypainting into a separate image file that will wrap around your object's mesh in Unity. This is called a UV texture. What makes things confusing is that it's often called a UV Map in casual usage, but a UV map is actually something else. The UV Map is the relationship between pixels on a UV Texture and points on the mesh. In ZBrush these are separate and distinct items. In many other programs, the UV Map and UV Texture are conflated to simplify things. Which makes it seem like ZBrush has an extra step when creating UV Textures for Unity and other 3D software.

Before beginning, save your project and your tool(s) in ZBrush. There will be opportunities for things to get messed up or confused.

Create the UV Map

0: Open up UV Master in the ZPlugin menu.

This is where we'll create the UV Map, the Texture itself comes later.

1: Click Work on Clone

This takes care of a bunch of stuff to prepare for making the UV without disturbing your original object. I've screwed up several meshes trying to go without it. My advice is to just use it, it makes things easier.

2: Turn on Symmetry if your object is symmetrical.
Symmetry will try to make a symmetrical UV map, which results in a symmetrical UV texture that's easier to edit by hand. If your object is just sort of symmetrical, you might give it a try, too.

3: Click the big Unwrap button.
This will unwrap the current tool. My advice is to work one tool at a time, and to reduce the number of tools to the minimum necessary before getting to this point to reduce the repetition of exporting meshes and maps.

4: Click Flatten to have a look at the shape of your UV map.
You will see a wireframe of the UV map, this is the form into which your object's polypainting will be projected to make a UV texture. If you're expecting to do any hand editing of the texture's details, make sure that the forms are not too distorted and that seams are not crossing critical areas of the mesh, like across the face of a character. If they are, you can use Control Painting to get a better mesh.

I'm not going to cover that in detail, there are good videos on this at Pixologic and on YouTube, but the short form is:

  • Click Unflatten to get the controls back.
  • Click Enable Control Painting
  • Click Protect, then draw red on the parts of your mesh where you absolutely don't want a seam in the UV map (like the face of a character.)
  • Click Attract, then draw in blue the areas that you'd like the seam to be (like the back of a character's head, or under their chin.)
  • Click Unwrap again and check the results using Flatten.

5: Click Unflatten to get your controls back.

6: Click Copy UVs to put your UVs from the Clone on the Clipboard.

You've now created a UV map, which you need to apply to your original object to guide the creation of a UV texture from its polypainting.

7: Select your original object from the Tool menu.
This will bring it back into the Document view and make it the active object. If something's wrong, or you can't find it, reload it using Load Tool (because you saved it before starting like I advised, right?)

8: Click Paste UVs in the UV Master menu.
This puts the UV from the Clone that's on the Clipboard on your object. It's now ready to have its texture map made from the polypaint on it.

9: Save your tool. Give it a distinctive name, like MyTool-withUVs.ztl.

10: Take a deep breath. The rest is pretty easy.

11: Open Multi Map Exporter under the ZPlugin menu.

12: Choose the things you want to export. Mesh and Texture from Polypaint for this example.

13: Choose FlipV to orient maps correctly for Unity.

If you want to have your map files in a specific format, select it in the Export Options and file names sections.

14: Click Create All Maps to create the UV texture and to save the mesh as an .OBJ file. This is one of the most poorly worded bits of button text in ZBrush. Even just "Save" would have made more sense. Oh, well, if we start talking about what's screwy with ZBrush's UI, we'll never finish.

15: Import assets into Unity (Assets=>Import New Asset...).


OK, that's the process. Having it all written out in detail makes it look worse than it really is, it actually happens very quickly once you know it. It's those first few passes that are a problem.

One of the things that really slowed me down in ZBrush is the fact that ZBrush doesn't tell you anything inside ZBrush about what the orientation of the UV map is relative to the base orientation of the mesh. If you open the Tools=>UV Map menu and start clicking the buttons like FlipV, FlipH, Cycle UV, Switch U<>V, it's easy to get lost really quickly as to which transformations you've applied. And there's no simple way to set it back to its base orientation.

Finally, what I ended up doing was creating the UV texture, while applying no transformations at all, then I opened it in GIMP & performed all the tranformations there, saving a clearly marked file for each. Then I pulled the mesh into Unity as well as all the versions of the map. I just drug maps onto the mesh object in Unity until I got the right one (FlipV.)

Colors from ZBrush

To make sure, I saved the map from ZBrush again with FlipV on, and it worked. But then I noticed something. The colors were off on part of the map in Unity. It looked OK in ZBrush and GIMP, but for some reason the color encoding came across wrong in Unity.

Left, Texture map in .psd straight from ZBrush. Right, texture map opened in GIMP and re-saved.

The quick fix was to load the map in GIMP then re-save. It may also be possible to use other file types, like .tif, and have the colors work out perfectly from ZBrush.

The Effects of UV Orientation
The map on the left was saved with FlipV on, the one on the right was saved without. If you get an object looking like the one on the right, check your UV map's orientation, or flip it vertically in an image editor (flip, don't just rotate 180.)

Mesh Orientation

The mesh orientation will get rotated front-for-back when going from ZBrush to Unity, too. It's just a 180 degree rotation, so it's not difficult to fix, just turn it around. If it's facing the camera in ZBrush, it'll be facing away when it comes into Unity.

The object on the left has been rotated to bring the 'F' side (Front) to face the camera, as it was saved in ZBrush, the one on the right is how it came into Unity.

Torn Edges on UVs

You'll notice in that picture of the back of the block above that there's some ragged stuff showing at the edges of the UV map. At first I blamed bringing the map through GIMP, but it does that straight from ZBrush, too. Fortunately the fix for that is simple, too.

For this simple texture, I just did a flood-fill of the black areas of the UV map with the background color (white). With a more complex texture, I would have used smudge or something like to bleed out the edges of the map a few extra pixels.

Map on the left has been cleaned up, UV on the right is as original, with visible seams.

Here are the maps used in the above image:

The original UV texture map from ZBrush.

The UV texture map with the black areas flood-filled with the foreground color of the object.

That's a Wrap

I hope that helps. If you feel I've been unclear anywhere here, or missed something important, please leave a comment or drop me an email message. If I've been helpful, let me know that, too!

Good luck with your ZBrush and Unity endeavors!

Monday, May 5, 2014

Kerbal Space Program + DayZ = ...Firefly?

Beside DayZ, I've recently started playing Kerbal Space Program. It's a game where you build rockets and send little green men off into space to land on their Mün and other planets in their little solar system. The physics engine lets it be moderately realistic in its behavior, enough for a game anyway. The build system is simple enough that a mere mortal can deal with it, or a rocket person who doesn't want to deal with lots of niggling details because nobody is paying them to do this.

I wrung the heck out of the demo version before I bought the full version. There are some significant differences between the two, aside from the obvious lack of features. For one thing, the simulation in the demo is more forgiving than the one in the full game. The full game does have the advantage that the simulation is more "fine grained" than the demo, though. This boils down to meaning that you have to pay more attention to how you build and fly your rockets in the full version, especially the large ones. The demo is more "gamey", in that you can slap together almost anything and get it into orbit. The full version requires a bit more thought and testing.

Recapitulating History

Since the demo's parts are similar to early NASA parts, I decided to get started by just putting together some simple tests to learn about building rockets in KSP.

My first was a capsule with parachute recovery (there's no other capsule or recovery system in the demo, so every flight is a "manned" flight.) I put this on top of a stack separator and a short tank with a large engine on the back and some fins for a bit of stability. I was worried that it would be too short to be dynamically stable along its length, that it would pitch or yaw wildly, but I decided to throw caution to the winds and launch it just to go through the process of getting something off the ground.

The real thing version of where I started in KSP

In spite of a lack of any control system, it flew just fine. It was about a 10 minute flight, surprisingly long for the amount of propellant, I thought. This basic configuration, sans fins, became the core of my next step--build a capsule and service module style combination that I could put on top of different boosters.

I added a dynamic control wheel system and some RCS jets to fill it out. Later, when I tried to use the RCS jets I learned that I needed to add RCS propellant tankage, too. It added a lot of weight, but at the end I had a solid core to build around for an orbital system.

This went on top of another stage separator, a taller tank, and another large engine for another suborbital test.

Mercury Redstone Suborbital Launch

That flight also went well. The fins of the first flight had been removed, and I decided to see how much stability I got with just the reaction wheel system and no fins on the booster. One thing that I missed immediately from the construction information was the lack of a display of the center of pressure on the craft. A basic measure of stability is where the CP sits with respect to the center of gravity (CG) of the craft. CP needs to be behind CG, and the greater the distance between them then generally the more stable the craft will be in the face of perturbations.

The other thing I missed was the lack of a sequencer to control the craft. It's a game, they assume that you want to "fly" the craft. I'm an instrumentation and controls engineer. I expect to build a solid program to get the craft to where I want it, then sit back and let it do its work. A sequencer is sort of a computer that looks at inputs from control instrumentation--acceleration, altitude, etc.--then does certain things at certain times--adjust valve settings, thrust vectoring positions, engine cutoff, etc.

That way you can let the sequencer manage engine throttling on the basis of altitude or velocity, engine shutdown on the basis of same, staging, and firing of the new stage (through that stage's control system.)

In KSP, there are a sequence of events set up linearly that are activated by the space bar. Engine activation (throttling happens elsewhere), stage separation, parachute activation (deployment is controlled by the parachute itself, which deploys as a drogue at high altitude then opens fully at about 500m.)

It more or less works, but having to "fly" each craft gets tedious for me. I'm of the school of aerospace engineer that feels the job is done when the vehicle gets off the ground. Then you just sit back and chew your nails till your bit completes its mission sequence.

Ascent to Orbit

The next step was adding some more power to the booster to get enough velocity for orbit. Given the sort of downrange distance I got with my suborbital vehicles (I flew 3 suborbital flights to different altitudes and downrange distances to get a feel for the craft and the controls), it wasn't hard to get a "seat of the pants" feel for what it would take to stretch the craft for orbital flight. Since the game doesn't give you much in the way of real numbers, that's about all you'll get. The "empirical method" rules here. But since it's just a game, it's not a surprise or much of a problem--I'm just used to having numbers for planning.

I added a second stage between my service module stack and my first stage stack, then added a couple of strap-on boosters to the first stage. Since I hadn't sorted out the sequencing of engines on the first launch, the strap-ons ended up being my first stage, rather than a "stage 0", with the core stage only firing after they burned out and were dropped.

I'd already noticed that the game's world behaves pretty much like our own world. It rotates the same direction, for example, so pitching over to the east would be the most efficient path to orbit. I fired up the booster--fortunately the strap-on boosters had enough thrust to get the whole stack of the ground--rode them up to a decent altitude, staged, then started tipping over to the east.

I took it slow on the tipping, since the whole rocket was so heavy that I wanted to make sure I got enough altitude. As it was, I rode the core stage up, staged, then continued the pitch-over to the east under power the full time. I know it's probably more proper to get the apogee high enough, shut down, then fire up again for a circularization burn at apogee, but I wasn't sweating that at this point.

Having only limited data on the main screen meant popping back and forth between the main screen and the map screen to check my trajectory. I wasn't sure if the game world had the same acceleration due to gravity as Earth, so I didn't know how much I could tell by my altitude and ground-relative velocity (and it bothered me that I didn't have a radar altimeter or some such to know my distance above ground, too. But that really bit me later, when I got to the Mün.)

I did manage to set up a decent orbit, and, yes, with a plenitude of propellant. I would be able to go home again. I played around with raising and lowering the orbit.

And here's where KSP gets really cool.

The immediate display of effects of acceleration on trajectory in the map window is really neat. It's easy to see what happens when you accelerate at different points of your orbit. It also gives players the chance to get stuck in orbit, revealing a bit of physics about energy use. And, even more significantly, changing orbital inclination.

One of the things that irks me is the common perception of "space" being like one big room, where everything that's "in space" is together. It's often presented this way in the simplified presentation of general media, and those people who don't have any direct contact with space work just don't know any better. They see the Hubble Space Telescope as hanging right off the front porch of the ISS, with all the spy satellites, weather satellites, commsats, etc, all right there in a row.

Now, every time I hear someone ask why the astronauts at the ISS can't just grab the Hubble and fix it, or why a Shuttle sent to repair a Hubble can't just ditch out to the ISS if something goes wrong, I'll wish that I could sit them down with a copy of KSP with objects in the respective orbits and let them find out through personal (non-lethal) experience why this doesn't work.

Back to my orbit. I didn't know what my parachute could deal with in the way of incoming velocity, so I decided not to come in from the higher orbit (about 400km), but returned to a lower orbit of about 90km before doing a re-entry burn.

The parachute held up fine. In fact, I learned that the system could deal with returning from orbits beyond 500km, but it was having trouble reducing velocity enough from around 750km. I didn't pancake any spacecraft, but I don't think I'd want to try a direct re-entry from 1000km. I don't know if the game engine does enough simulation to cause the heat shield on the capsule to fail, either. In general, I didn't push it.

I flew several more orbital flights, with minor tweaks to my vehicle design (like having the core booster fire at launch along with the strap-ons). I used different techniques for getting to orbit, in one case going straight up until I had an apogee of 500km, shutting down, then tipping to the east and firing to circularize at apogee. It worked just fine. I also did the routine of going a bit to the east, raising my apogee to about 90km, shutting down then firing a second burn at apogee to circularize. It may have been more fuel efficient than going straight up before circularizing, but it wasn't as easy to fly.

I picked 90km as my altitude just because that's the simulated altitude I've used on numerous test programs to test equipment in space-like conditions of atmospheric pressure (or lack thereof.) I've used other targets as well, like 75km, but I went with 90 because I wanted a little room. And, I was glad to see that KSP seems to pretty well mimic Earth so that I can use familiar numbers like these.

Final Thoughts

KSP should be played in schools, for credit. I would like to think that it can be used without taking away the fun, and that kids could be induced to set objectives for themselves similar to actual space program objectives (rather than just blowing up little green Kerbal people or ramming them into the ground at supersonic velocities.) The game has tremendous potential for teaching, in a "seat of the pants" way, information about ballistics and orbital mechanics. Then, when these subjects are encountered in math and physics classes, the concepts will already be familiar.

While on Facebook, there was a little game someone started of asking what you'd get if you combined the two computer games you were playing presently. In my case it was DayZ and KSP. I figure mixing zombie apocalypse with rickety build it yourself interplanetary space flight gives something like a Firefly game (Reavers=zombies in this case, in case that's not obvious.)