Spent a good bit of the night (and morning) on this, so here goes:
I was looking for a way to pull a splatmap from a Unity3D Terrain and stick it in a PNG to use with another tool. I needed the splatmap to be rotated 90˚. Unfortunately, once it was actually out and in a PNG, it was transparant. More code so that I could edit it. And then once saved, the new properly-rotated version wouldn’t work. More code.
Eventually I got it all working. In an effort to hopefully save someone else many hours of muddling through the same way I did, I’ve cleaned it up a little and hopefully made it easy (enough) to use.
Splatmap Helper
(link is at the end)
…a small tool to help you export Unity3D splat maps, converting them to PNG.
Here’s what it can do:
- Converts a Unity Terrain Splatmap to a PNG that can be edited with your favorite image editing program.
- Takes your new PNG and converts it back into a “splatmap-friendly format”.
- Inserts that new PNG into the splatmap of one of your Unity Terrains.
Important to note that these are all separate functions. So if you just need #1, great. Or if you’ve hand-made a splatmap, aren’t using Unity’s Terrains, and just need #2, fantastic. Hopefully if you’re here, it’ll help you do whatever it is you need to do.
There’s info that shows up with each option so that you’re hopefully able to get things working.
Before you get too excited though, here are some caveats:
- It’s not heavily tested. I’ve destroyed a few PNG’s/splats along the way. MAKE SURE YOU BACK UP YOUR PROJECT BEFOREHAND!!!
- The workflow is quite short but is VERY specific which is really annoying (sorry). For example, #3 requires you to select the splatmap from within the Terrain within your Asset folder, then run the tool and from there, select the PNG which may have to be marked read/write. If you select the game object instead of the terrain/splatmap, it won’t work. If you do it in reverse, it will do the reverse. If the PNG isn’t read/write, it might not work. It’s really not flexible/robust.
- To pull the splatmap into an editable PNG, it has to basically drop the alpha channel that stores the splat for the 4th texture, and doesn’t re-add it until the 2nd step, which means if you were hoping to edit the splat for the 4th texture in photoshop, you’re out of luck.
- When it does re-add the alpha channel in the 2nd step to restore the 4th texture’s splat, it does so by subtracting the R+G+B channels from 1.0. Usually this should give you the original 4th texture again, but no promises. YMMV. Note that if you’ve got an image editor that WILL handle a splat with the alpha intact and you find you’re losing info about the 4th texture, you can comment out lines #69-74 and you’ll get the splatmap intact.
- After you use the 2nd tool (readding the “A” channel), the image might look totally transparant when it comes time for #3. Don’t panic – as long as it works when applied back to the terrain, you’re good.
- Any time you want to read from an existing PNG or write to an existing PNG, you will likely have to select it beforehand, and set it’s Texture Type to Advanced, and then add the Read/Write flag.
- You’ll want to keep an eye on the Debug log for anything that goes wrong.
Usage (assuming you’ve backed up already!):
(you will need to put the script in an Editor folder, such as “Assets/Editor”)
- To copy a Unity Terrain Splatmap to a PNG ->
- Find and select the splatmap in your assets folder (it will be within the terrain assset). Unity3D usually calls the terrains something like “New Terrain #.asset“, and you’ll have to find the splatmap inside – it’s usually the only child object.
- With the splatmap selected, run the tool. In the top menu bar, you should have a Terrain/SplatmapHelper/1-SaveSelectedSplatmapToPNG option. Choose it.
- The tool will ask you where to save the PNG. I suggest creating a new file (overwriting one may not work if the read/write flag is not set).
- Done. Check the Debug log for errors. Assuming all went well, you should have a new PNG you can edit/etc.
- To convert a PNG back to a “splatmap friendly” format ->
- Select the PNG (the one you’ve likely edited and saved twice in case something goes wrong!).
- Set it’s Texture Type to Advanced, and then add the Read/Write flag so it can be read from without issue.
- With the PNG selected, run the tool. In the top menu bar, the tool should be located at Terrain/SplatmapHelper/2-TurnPNGBackIntoSplatmapFormat.
- It will ask you where you want the output PNG saved. Find a location and save it.
- Note that if you view the new PNG from within Unity, it will usually show correctly (red green and blue). If you view it from within anything else, it might be transparent. Don’t panic.
- Done.
- To replace a Unity Terrain Splatmap with a new PNG ->
- Make sure the PNG has had it’s Texture Type set to Advanced and the Read/Write flag enabled so it can be read from. If you just finished the previous section, you still have to do this again for this new file.
- Select the splatmap within the terrain in your assets folder (not the gameobject!). This is exactly like what you did in the first section.
- With it selected, run the tool. This time, the final option. Terrain/SplatmapHelper/3-ReplaceUnityTerrainSplatmapWithNewPNG.
- It will now ask for the PNG that will be used to replace your terrain’s splatmap.
- REMEMBER that the PNG may show up as TRANSPARANT in the file browser! Don’t panic if it does – it’s to be expected.
- Done. You will have to hit “ok” a final time for the terrain to update. Make sure the debug log has no errors.
- If the terrain shows as all-white, you may have missed step#2 (or had an error during it).
Download
It’s 1 tiny script (this writeup is longer than the code). It’s in .js simply because the first code snippet I’d come across was js so I figured I’d get a little practice in some non-C#.
Few options depending on your preference (they’re all the same):
Unity Package (it’s just the script which puts itself in in Assets/Editor, no extras):
/download/SplatmapHelper.unitypackage
JS file (MUST place in an Editor folder – you may have to right-click/download):
/download/SplatmapHelper.js
Zipped (MUST place in an Editor folder after unzipping):
/download/SplatmapHelper.js.zip
Credit/Thanks to:
- Kragh of the Unity3D forum for posting some C# code that handles the transparancy issue in a nifty way ( http://forum.unity3d.com/threads/encode-to-png.214663/#post-1439634 ).
- VivienS for a UnityAnswers comment that aided in putting this together as well ( http://answers.unity3d.com/questions/13479/exporting-terrain-splatmap.html ).
- The many others who ask/answer questions on the Unity forums on a regular basis.
If you run into any issues, please leave a comment below. Otherwise, hopefully it helps someone else out there!
After step1, generated png file doesn't have an alpha. It imports as DXT1(or RGB when truecolor) on windows platform. When doing step 2 on that file, output file doesn't create an alpha.
But if I switch the texture to RGBA 32bit from import settings before step 2, file automatically has a blank alpha, and step 2's output is correct.
(Unity 5.3, PC&Mac Standalone, Windows 10)