Neck and Upper Body Tattoo Effect

In this tutorial you’ll learn how to create your own realistic neck and shoulder tattoo effect using 2D body tracking and 2D body landmarks. You’ll also use occlusion so the tattoos are hidden under the clothes, and when the user tilts their head, as they are in real life.

To follow along, download the example project and open the unfinished effect. The tattoo textures you need for this effect are listed in the Assets panel:

No Regrets by Tom Grunwald

Adding the tattoo canvas

Start by adding a rectangle as a child of a canvas. Rename it neck_tattoo and resize the Width and Height in the Inspector to 80 pixels.

The rectangle will be positioned at the top left corner of the canvas, in line with the default pivot point in Spark AR Studio. You’ll control the position of the rectangle dynamically using the body finder, body select and Neck 2D patches.

Add these 3 patches from the menu and connect:

  • The Bodies output of the Body Finder patch to the Bodies input of the Body Select patch.
  • The Body output of the Body Select patch to Neck 2D patch.
  • The Neck 2D patch to a patch representing the 2D position of the neck_tattoo rectangle. Learn how to make patches from Inspector properties here.

The patch graph will look like this:

The rectangle is now placed at the user’s neck where we want our first tattoo to be. It’s jittering because it's constantly updating due to subtle changes in the user’s movement. You'll stabilize the jittering and center the rectangle in the neck using the math patches: Subtract and Exponential Smoothing.

Positioning the canvas

You need to shift the pivot point to the left slightly, to place the rectangle exactly at the center of the neck. You can do this by adding a Subtract patch to edit the rectangle’s position values. Go ahead and add a Subtract patch. Then:

  1. Connect the Subtract patch between the Neck 2D and the 2D position patch for the neck. The Neck output should be connected to the First Value input of the Subtract patch.
  2. Change the Subtract patch data type to Vector 2. The rectangle is expecting to receive two values.

Finally, edit the Second Value to:

  • X: 40
  • Y: 20

The final graph and rectangle position will look like this:

Now, you just need to smooth out the tracking movement. To do this:

  1. Add an Unpack patch (set to Vector 2), Pack patch (set to Vector 2) and 2 Exponential Smoothing maths patches.
  2. Add 120 in the Damping input of both Exponential Smoothing patches.
  3. Connect the patches as in the graph below:

The Unpack patch splits the Neck 2D patch coordinates into two separate channels, intercepted by an Exponential Smoothing patch on each side of the channel. This dampens the signal before packing it back into the 2D Position patch for the neck rectangle.

We reduced the value in the Exponential Smoothing patches from the default 200 to 120 because we don't want to dampen the signal too much and cause the tattoo to change positiion.

This is what your final position graph will look like:

Adding the tattoo material

Next, create a material for the neck_tattoo rectangle, rename it neck_material. Then, with the material selected in the Assets panel:

  1. Go to the Inspector and change the Shader Type to Flat.
  2. Apply the texture: neck_tattoo, to the material.
  3. Staying in the Inspector, change Blend Mode to Multiply. This makes sure that the texture blends with the skin tone.

Hiding the tattoo behind the face

Next, we’ll use an occluder to cover the user’s face to make sure the tattoo is not visible on the user's face.

First, with the neck_material still selected in the Assets panel, go to the Advanced Render Options in the Inspector. Clear the box to the right of Write to Depth Test. This keeps the tattoo behind the face texture you're going to make, so it’s not interfering with it.

Now, to create the occluder:

  1. Add a face tracker and a face mesh and rename the mesh: face_occluder.
  2. Extract the face tracker texture from face Tracker0.
  3. Create a new material, rename it face_material and add it to the face_occluder.

In the Assets panel, select face_material, go to the Inspector and:

  1. Set the Shader Type to Flat. Apply the texture: faceTracker0.
  2. Expand the Advanced Render Options and clear the Write to Depth box.

Finally:

  1. In the Scene panel, select the face_occluder face mesh.
  2. Go to the Inspector, unselect the boxes to the right of Eyes and Mouth. This removes the outline of the eyes and mouth from the face tracker texture.

Now our tattoo follows the neck but is hidden behind the face so it's not visible when it shouln't be.

Hiding the tattoo behind the clothes

You're going to use the camera texture, person and skin segmentation to hide the tattoo behind the user's clothes.

With the Camera selected in the Scene panel, in the Inspector, create the following three textures:

  1. Camera texture (Texture Extraction).
  2. Person and skin segmentation textures.

The person and skin segmentation textures will be listed in the Assets panel as segmentationMaskTexture0 and segmentationMaskTexture1. Rename them:

  • person_segmentation
  • skin_segmentation

Staying in the Scene panel, add a rectangle and rename it cloth_occluder. Change the size of the rectangle, so it’s the same size as the canvas. To do this:

  1. In the Scene panel, select cloth_occluder.
  2. In the Inspector, click each box next to Width and Height and select Fill Width and Fill Height.

Next,

  1. Create a new material. Rename it cloth_occluder_material
  2. Change the Shader Type to Flat and clear both options under Advanced Render Options
  3. Add the material to the cloth_occluder rectangle
  4. Create a patch representing the cloth_occulder_material diffuse texture.

Drag the CameraTexture0, person_segmentation and skin_segmentaton textures from the Assets panel to the Patch Editor. Add two more patches: Pack and Subtract.

The Patch Editor will look like this:

Now let’s build a graph with these six patches. Connect:

  • The RGB output (the middle output) of CameraTexture0 to the top input of the Pack patch (set to Vector2).
  • The Pack patch output to the Diffuse Texture property for the cloth_occluder_mat patch.

So far nothing has changed. This is because the cloth_occluder_mat is expecting an RGBA value and at the moment we're sending the RGB value from the camera texture.

You'll get the Alpha value you need from the person and skin segmentation patches. Connect:

  • The Alpha output of the person_segmentation patch to the top input of the Subtract patch.
  • The Alpha output of the skin_segmentation patch to the bottom input of the Subtract patch.
  • The output of the Subtract patch to the bottom input of the Pack patch.

Your graph will look like this:

This graph subtracts the Alpha value of the skin segmentation from the Alpha value of the person segmentation and packs the remaining Alpha value back into the Diffuse Texture patch.

Congratulations! You’ve now created a neck tattoo effect, with the tattoo realistically behind the user’s face and under the clothes.

You’ve also learnt how to use segmentation and body landmark tracking in Spark AR Studio, capabilities you can use to build all kinds of fun and immersive experiences.

Complete the extra credit section to add some finishing touches to your effect.

Extra credit: Adding shoulder tattoos

With the face and cloth occlusion already set up, you can simply repeat the first parts of this tutorial to create two more tattoos and position them on the right and left shoulders.

To get going, in the Scene panel, create two more rectangles. Make sure to position them above cloth_occluder rectangle. Rename them: right_shoulder_tattoo and left_shoulder_tattoo. Your Scene panel will look like this.

Next,

  1. Add a material to each rectangle.
  2. Rename each material right_shoulder_material and left_shoulder_material.

Starting with the right_should_material selected, In the Inspector:

  • Change the Shader Type to Flat.
  • Add the right_shoulder_tattoo texture to the right_should_mat.
  • Change the Blend Mode to Multiply.

Repeat these steps for the left_should_mat and left_should_tattoo.

The tattoos are positioned at the top left by default. We’ll temporarily turn off the cloth occlusion visibility, so we can see both tattoos while we position them on each shoulder. We’ll turn the visibility back on later. For now, in the Assets panel:

  1. Select cloth_occluder.
  2. To the right of Visible, unselect the box.

Now, we’ll add the patches we need to track the new tattoos to the shoulders. In the Patch Editor:

  1. Add a Left Arm 2D patch and a Right Arm 2D patch.
  2. Connect the input of both patches to the output of the Body Select patch.

This is what your patch graph will look like:

Then:

  1. Create patches for the 2D position of right_shoulder_tattoo and left_shoulder_tattoo.
  2. Connect the Left Shoulder outputs of Left Arm 2D and Right Arm 2D to the corresponding 2D Position patches.

The left shoulder tattoo is in view due to the top left pivot placement, but the right shoulder tattoo is slightly out of place.

As you did with the neck tattoo, you'll use a Subtract patch and Exponential Smoothing patches to position the right shoulder tattoo.

First copy and paste the following patches, connected to the Neck 2D patch.

  • Subtract.
  • Unpack.
  • Exponential Smoothing.
  • Pack.

Then connect these patches between the Left Arm 2D patch and the 2D Position patch for the left_shoulder.

Repeat this process for the Right Arm 2D patch.

This is what your final graph will look like:

The tattoos are correctly placed!

All you need to do now is turn the occlusion back on. In the Scene panel:

  1. Select cloth_occluder.
  2. In the Inspector, to the right of Visible, select the box.

Your tattoos are now hidden behind the user’s clothes.

Was this tutorial helpful?