Using curves, instances, and emission to bake stitching and seams for clothing assets (Ucupaint+Shader nodes)

On:

|

,

|

One thing I greatly miss from Substance Painter is its “draw on curve” feature. Being able to create curves and then use them to “stamp” patterns was extremely helpful, and it’s a shame that Blender does not have a feature like that.

HOWEVER

With Blender’s new raycast shader node, this is easier than ever to achieve! Let’s get those stitches baked!

Things you’ll need

  • Ucupaint
  • A clothing asset that has clean topology (i.e. not a sculpt)

Setup

Here I have a shirt that I’m doing for a friend. On the left you see the stitches I already baked in preparation for this post. I also have a nice woven fabric procedural material I learned from Ryan King here, though that part is not important for this tutorial.

For your clothing asset, make sure that you have clean topology that follows the natural patterns of how clothes are cut. I also like to arrange my UVs with minimal stretching and to straighten parts that I want to have logos and such. You can use Mio3 to help you get nice, clean UVs.

In the texture paint window, add a new Ucupaint material setup, and then click the + icon to add a new layer with Solid Color w/ Image Mask. This image mask is going to be our bake target for the seams. Make sure it’s 4096×4096, since we want the mask to be as high quality as we can get away with.

I set the color of the layer to be black and for the time being, and made that mask affect only the color channel. This can be changed layer to make your seams and stitches have different colors, but right now we just need to be able to see things clearly, so black on white made sense.

Now, we could go about simply painting the seams and stitching all by hand, and if you have good brush texture packs, you can do this fairly well. I, however, absolutely hate doing that, and most of all, I hate the inconsistent look. Depending on view angle, you can get the stitches to warp, or look different sizes, or be angled wrong. It just sucks.

The solution to this is to recreate Substance Painter’s curve draw, and the linchpin of this is the Raycast node, curves, and the curve to tube modifier.

Creating curves

For this setup, the easiest possible method is to use the geometry we already have as the basis for the curves.

Use Shift+D on the edge loops where you want your seams to be, then press P to separate them into a new mesh. Exit edit mode on the main cloth mesh, find the separated mesh, and then convert it into a Curve object. Then you can add the Curve to Tube modifier.

Doing this will yield a thin tube that follows the exact contour of the original mesh, but because it has thickness, it now intersects with the main cloth mesh. This is exactly what we want.

Baking intersections in Shader Nodes

Now that we have a cloth asset and another asset that intersects with it, we can use Raycast to capture that into an image texture. Let’s go to the shader nodes tab and set it up for baking.

Set up your shader nodes like this. Disconnect the Principled BSDF the Ucupaint node is connected to from the Material Output, because for baking, we need to make the material look at just the emission.

You want to add a Raycast node, a Normal geometry node, and an Emission node. You connect the Normal to the Direction input of the Raycast, and the Is Hit of the Raycast to the Color of the Emission, and then you plug that to the Surface in the Material Output. For the length, set it to a very low value. We only want to detect a hit really close to the curve tube, but not detect anything else, like the mesh’s own geometry, or other objects in the scene.

For this, you’ll also want to add an Image Texture. When you add it, find the name of the layer mask you created earlier and select it. You want this image to be selected when you bake so that we can bake the intersection.

Go to the Render tab on the right, then scroll down to the Bake section.

Here, you’ll want to change the bake type to Emission. On the target, it’ll be Image Textures. Make sure Clear Image is unticked, because we want to be able to keep adding to this image without removing other baked details.

EXTREMELY IMPORTANT: Whatever image texture you have selected (i.e. clicked on) will be the target. You need to be absolutely certain that it’s the image texture you want to bake to that is currently selected. If the image texture node has a white outline, that means it’s currently selected. Do not bake unless you have the right image selected, otherwise you can overwrite other images you’ve already baked.

Once you have things set up how you want, you can click Bake, and it should yield an image that captures the intersection between that tube and the mesh. You can now hide the curve tube.

Let’s take a look at what we got.

Cool!

With this knowledge, now you can convert other edges and loops in your mesh into tubes, and then bake them too! I added some extra curves to the seams under the arms and on the sides of the body.

A bonus of doing things this way is that if you reconnect the Principled BSDF to the Material Output, you get to see where the mask is affecting, since the image we just baked to is the same one being used by Ucupaint as a layer mask.

Stitching

Now that we know how to capture the intersection of a mesh as an image, we can use the Array modifier to instance objects on the curves to create different patterns! Add a new image layer with a new texture mask in Ucupaint, and let’s do some stitching!

Creating the curve

As we did just now, select an edge loop you want to use for your stitching, duplicate it, and separate it. After that, convert it to a curve and give it a new name.

Creating the instance object

Blender’s Array modifier is very powerful. It allows you to instance objects in many ways, and one of the coolest is instancing along a curve. To make use of this, let’s create the instance object for the stitches.

  • Add a plane.
  • Select the top and bottom edges.
  • Delete only those edges.

Now you have two parallel lines. Convert them to a curve, and then use the Curve to Tube modifier to create a set of parallel stitches!

In the Curve to Tube modifier, the caps can be changed from Flat to Round for a nicer look.

Now, you should also scale this object down and apply that scale so that it’s the correct size. You may also want to go into the object and bring the two parallel lines closer together.

Once your stitch object is looking good, it’s time for the Array modifier.

Instancing along a curve

On the stitch instance object, add the Array modifier. Change its shape to Curve, and then select the curve object.

Bump the Count way up so that the stitching looks correctly spaced.

You will also want to adjust the rotation by ensuring the forward and up axes are the right ones so that the stitches can lay flat against the cloth.

You may also run into the issue where the stitches are tilting incorrectly as they run along the curve.

This means that you need to go into the Curve object (i.e. not the stitch instance) and use Ctrl+T to adjust the tilt on the curve control points.

For best results, make sure that all of the stitches are laying flat and intersecting with the mesh.

Baking

As with before, go to Shader Nodes, and use a new Image Texture node to pull up the layer mask that we created earlier. I prefer to separate the seams from the stitching, hence why they are two separate image masks.

Same as before, connect the Emission shader to the material output, make sure your image is highlighted, then head over to the bake tab, and click Bake.

Now you can hide your stitch instance, connect the image texture to the material output, and see the result of your bake!

Now you have all the tools and knowledge necessary to bake all the stitches and seams you want!

Results

Doing this process a few more times, we now have perfectly positioned stitches and seams on a shirt as a set of black and white masks that we can then use on Ucupaint however we want!

Substance Painter can suck my nuts.

Posted by

in

,

Leave a Reply

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