Voxel Workflow with 3D-Coat & MeshLab

Back to overview

Hello there! My name is Phil (aka NomadKing) and I’m an Artist, Game Developer, and Sketchfab Master from the UK. In this tutorial we’re going to look at creating a unique texture for a voxel model and discuss a few simple techniques you can use to enhance your voxel work.

To do this we’ll be using 3D-Coat, MagicaVoxel and MeshLab – so let’s get started!

The Problem with Voxels…

The most common question I get asked about working with voxels is how to improve the appearance of your final scene. Whilst it seems like the answer should be as easy as saying ‘the same way you improve the look of any scene’, it’s not quite that simple.

My goto voxel editor is MagicaVoxel – it’s a great tool and provides us with a great amount of export options. However, none of them let us treat our voxels as a ‘standard’ model. Exporting as an OBJ file is the closest it comes, but the lack of unique UV’s leaves us unable to use complex texture based effects (such as lightmaps) to bring some final polish to our work.

To fix this issue we’re going to export two versions of our model from MagicaVoxel, then use a combo of 3D-Coat and MeshLab to give us our unique UV’s and base texture.

Preparing the Models

First we need a version of our scene that contains all the colour information in vertex data. After opening our Temple model in MagicaVoxel, head to the bottom right and click Export, then PLY. Since we’re going to have a few files floating around it’s a good idea to use a naming convention to keep track of everything – call this one Temple_COLOUR.

Colour version of our model Exported as PLY

Next we’re going to flat fill our model with a single colour and export an OBJ version for our mesh. Usually when MagicaVoxel exports an OBJ file it will create extra geometry every time the colour on a face changes – but by flat filling our model first – we can ensure that the minimum amount of faces are created by the export.

Mesh version of our model Exported as OBJ

To do a flat fill, simply select the Paint mode while using the Face brush, tick the XYZ axis options, and click the model once. It doesn’t matter what colour we use – the goal is for it all to be the same. Next click the OBJ export option and call the model Temple_MESH.

That’s the prep work done. Time to make some UV’s!

Texture Coordinates

To make our UV’s we’re going to take our minimal geometry mesh into 3D-Coat, get rid of the palette based UV’s and generate some unique ones.

Start by opening 3D-Coat and then:

  • From the popup window select ‘UV Map Mesh’.
  • When the Open dialog appears, pick our Temple_MESH model and hit Open.
  • On the Import Dialog, change the ‘UV Map Type’ to Auto-mapping.
  • Tick the ‘Lock Normals’ option, set the ‘UV Set Name’ to Mesh, and the width/height to 4096.
    Click ‘Ok’

You should see a progress bar in the middle of your screen, and after a few moments a brightly coloured version of our model will appear.

Auto generated UV’s in 3D-Coat

The bright colours we see are 3D-Coat’s way of showing the separation of faces into UV Islands – this means it worked. Our import options have gotten rid of the old UV’s and automatically generated some new unique ones for us.

3D-Coat offers a huge amount of UV tools that we could use to tweak, scale, re-arrange and play with our UV’s for the rest of time – but for what we are doing we can live with the auto-mapped ones. However, if you feel the need to improve them further, this 3D-Coat:UV’s tutorial by Alex Meister is a great place to start!

Let’s export our improved mesh:

  • On the menu go to File > Export Objects & Texture.
  • Make sure ‘Export Geometry’ is ticked.
  • Set the file type to OBJ, select the Temple_MESH file from the browser, click ‘Save’ and confirm the replacement.
  • Change the ‘Texture Export/Import Workflow’ to Gloss/Colour Specular.
  • Untick all of the other options apart from ‘Export Color ‘ and ‘Apply Padding’.
  • Change the ‘Color Extension’ option to PNG and click ‘Ok’.

As well as exporting our new UV’s this exports an empty texture file. We don’t strictly need this texture, but without it MeshLab seems to hit an error part way through the conversion process – so we’ll have to live with it for now and clean up any useless files once we’re done with the next step.

The Base Texture

Now that we’ve prepared the two versions of our model we can take a quick trip into MeshLab to bake our base texture. We’ll also need to fix a rotational difference between our models before we bake – in PLY files Z is up, but in OBJ files Y is up.

Once we open MeshLab:

  • Go to Import Mesh and select the Temple_COLOUR model.
  • We need to rotate this mesh, so select the Manipulator Tool from the top bar and click on the work area.
  • Press R to enter rotation mode and then X to select the axis we want.
  • Hold shift and drag to rotate until ‘X global’ is at -90.
  • Press return to confirm the change and click the Manipulator Tool again to exit the mode.
  • Go to Import Mesh and select the Temple_MESH model.

Our 2 meshes should be imported and perfectly aligned – you can check this by toggling their visibility using the ‘eye’ next to their names in the Project view (on the right hand side).

We can now bake the vertex colour data into a texture:

  • Go to Filters > Texture > Transfer: Vertex Attributes to Texture (1 or 2 Meshes).
  • Set the Source Mesh as Temple_COLOUR.
  • Set the Target Mesh to Temple_MESH and the Texture File to Temple_Base. This will be the name of the new texture we create.
  • Set the Texture Width and Texture Height to 4096.
  • Tick ‘Fill Texture’ and ‘Assign Texture’ then click ‘Apply’.

Baked Texture applied to our Mesh in MeshLab

After a few moments the process will complete. If you hide the Temple_COLOUR mesh in the Project view, you should see the colour now baked as a texture and assigned to our Temple_MESH model. The baking process will have created the texture in the directory with our models, so we don’t need to worry about saving or exporting anything.

Now that Temple_MESH.obj has our unique UV geometry and Temple_Base.png is our texture, let’s see how the results look on Sketchfab:

At this point the technical work is done, and our voxel piece has become a standard model – great news! But what if we want to go further? What could we do to improve the end result? Luckily, 3D-Coat’s paint room offers us a great set of tools to add some simple but powerful effects to our texture work.

You can do all these effects on separate layers inside 3D-Coat and export the final texture, or export them individually for more control in an external image editor. In the end whatever you’re most comfortable with is usually the best!

Ambient Occlusion

The addition of non-directional shadowing will really help bring out the shape and fine details in our scene, and with all the angled edges / geometry in a voxel model, Ambient Occlusion (AO) is a great effect to use. This can either be baked in a 3D package or done at real time (with the new Sketchfab SSAO filter).

Using a real time effect has a performance cost, but gives us more accurate results in relation to your lighting, or when used on an animated model. You can also change / edit your model without needing to re-bake anything making it great for a WIP pipeline.

Baked AO typically gives us more control over the end result and no performance cost – but is more suited to static scenes and may give a less realistic result with real time lighting. Since realism isn’t a concern for stylised work, I often choose to bake my AO.

Ambient Occlusion baked in 3D-Coat

In 3D-Coat this can be done by selecting ‘Textures > Calculate Occlusion’ from the menu. Usually I apply my occlusion as a ‘Multiply’ layer at 50 – 70% opacity.

Height Gradient

Known by several different names, Height Gradients provide a way of emphasizing the height and volume of a model using subtle gradient colour changes. They are very commonly used in stylized 3D work.

For this piece I would keep things simple and use a single gradient covering the full height of the model, but gradients can be a powerful tool and it’s not uncommon to use them for smaller elements – such as the treebark or stone areas – to create more controlled effects.

A Height Gradient used in 3D-Coat

In 3D-Coat gradients are done using the ‘Fill Tool’ with the ‘Gradient Mode’ option ticked. For the colour at the top of the model I’ve used a pale yellow (#FAF9BE) and at the bottom a deeper turquoise (#2F656E). I typically apply my gradients in ‘Overlay’ mode at 25-50% opacity.

Summary

This brings us to the end of this tutorial. We’ve gone through the steps needed to convert your voxel model into a standard mesh, and talked about a few simple steps you can take to improve your final look. Hopefully you’ve learned something – but even if you haven’t – thanks for taking the time to read this far.

To finish things off, below is a version of the Temple model that has both the Ambient Occlusion and Height Gradients added to the base texture. Probably a biased opinion, but I think it looks great!

About the author

Phil Clark

Art Monkey, Part-time Coder and Sketchfab Master from the UK.


Leave a Reply

Your email address will not be published. Required fields are marked *

  • dan says:

    Being a newbie I don’t really understand what all that work achieves. I’d like to see some befor and after comparisons.

    • Phil Clark says:

      Hi Dan,

      The MagicaVoxel OBJ export doesn’t have unique UV’s, so while it would look almost the same as the ‘Scene 1’ version, you wouldn’t be able to do the texture based effects that ‘Scene 2’ shows.

      This workflow is just one of the way you can address that issue.

  • EXM says:

    Awesome workflow, thanks for sharing, Phil!

  • Simon Kratz says:

    Amazing work, Phil! I love the unique style of your voxel work and it’s great to have some insight into your workflow!
    Please make more of these tutorials! 🙂

  • hansolocambo says:

    That’s an outstanding workflow ! What I just read probably explains the very impressive choice of colors on most of your models. The ONE step I didn’t know at all about, and I’m glad I came here just for that reason !, is the Height Gradient in 3D-Coat. I honnestly never heard about that and I’m sure gonna give it a try on my next sketchfab exports 😉
    Thanks a lot for sharing your talented and imaginative workflow with the community. And maybe (personal opinion) move on from the voxel meshes someday ? They have a nice style that’s for sure, but downside is they cannot really be optimized into lower poly objects because of the multiple 90 degrees angles. What I mean is that you’d be a great asset in the dev team of a video game with your style and ideas. But for that you need to move on to lower poly objects.
    Keep up ! Thanks again.

    • Phil Clark says:

      Happy that you found something useful in this, and thanks again for the kind words – I’ve never been complimented on my choice of colours before. 😉

      While I am doing a lot of voxel pieces at the moment, I am working to improve my work in other styles. I’m a huge fan of hand painted textures – but learning to hand paint textures to a high standard can be quite time consuming!

  • Minecraft PL says:

    This is amazing. Can you make tutorials for Minecraft schamatics or maps for newbie users? Thanks Phil.

  • myNours says:

    Hi!

    I’ve been trying and trying like… 10 times in a row, but i keep getting the same issue ;
    In MeshLab, every time i use filter “Transfer: Vertex Attributes to Texture (1 or 2 Meshes)”, the generated texture is… all black.
    I’ve double, triple-checked even all steps and i’m sure i did everything as told :/ (i even named all my file EXACTLY like yours :D)
    I don’t know whether i’m doing something wrong or it’s a software version issue?

    For the record, versions used:
    MagicaVoxel-0.98.2
    3D-Coat 4.7.35 (x64 version)
    MeshLab_64bit_fp v2016.12

    Oh and, one thing i noticed, on one of your screenshots (https://blog.sketchfab.com/wp-content/uploads/2017/03/image03-3-600×500.jpg) i see “Applied filter: Set Texture” in the bottom right, and this doesn’t show up for me at this step =(

    And second little detail, when importing mesh in 3d-coat, i get the same checked rainbow as you do, but i don’t have any shadows…

    Anyway, thanks for (what seems to be :D) your great tutorial, and hope you can find some time to help me ^^

Related articles