Smooth Meshes on Unity3D (Mesh Subdivide)

Graphical interfaces on computers work by discretizing an environment. For example, when you see a circle on your screen, it’s shaped by showing a finitude of dots (pixels) tangent to the circle. As there is a multitude of pixels to represent the circle, you have the perception that the circle is smooth, as you cannot see these individual pixels in naked eye.

Raw vs Smooth Mesh
Raw vs Smooth Mesh

A similar thing happens when you’re dealing with meshes, but instead of circles or lines, you’re dealing with triangles in a 3D environment. A multitude of triangles tangents to the mesh connects to one another to forge the desired mesh shape. The more the triangles, the smoother and more similar to the original shape is the mesh.

Sometimes when you’re handling a mesh in Unity, it may look sharp on the edges. One of the easiest ways to correct this is to increase the number of triangles on the mesh.

When using this method (steps on how to reproduce it described below), you will get a result similar to this one:

Non-Smoothed vs Smoothed Mesh Comparison
Non-Smoothed vs Smoothed Mesh Comparison

This method is specially helpful if you want to change the mesh shape in runtime (for example, if the user interacts with the application shaping the mesh).

How to setup

To easily make a mesh smoother, you will need to create two scripts in your Unity project.

One script is responsible for the algorithm to subdivide the triangles in the mesh (available on Unity Community Wiki) and the other is an abstraction layer to show the user the available options to smooth the mesh.

Import Scripts

You must create two new scripts in C# (MeshHelper.cs and MeshSmoother.cs) and place them in your project folder as following:

.
└── Assets
    └── Scripts
        ├── MeshHelper.cs
        └── MeshSmoother.cs

MeshHelper.cs

Code available on Unity Community Wiki.

MeshSmoother.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshSmoother : MonoBehaviour {

    MeshFilter meshfilter;
    Mesh mesh;
    Vector3[] vertices;
    int[] triangles;

    private int[] subdivision = new int[] {0,2,3,4,6,8,9,12,16,18,24};

    [Header("Subdive Mesh")]

    [Tooltip("Divide meshes in submeshes to generate more triangles")]
    [Range(0, 10)]
    public int subdivisionLevel;

    [Tooltip("Repeat the process this many times")]
    [Range(0, 10)]
    public int timesToSubdivide;

    void Start () {
        meshfilter = GetComponent<MeshFilter>();
        mesh = meshfilter.mesh;
        vertices = mesh.vertices;
        triangles = mesh.triangles;

        for (int i = 0; i < timesToSubdivide; i++)
        {
            MeshHelper.Subdivide(mesh, subdivision[subdivisionLevel]);
        }
        meshfilter.mesh = mesh;
        vertices = mesh.vertices;
    }
}

Setup Script

Now, you need to Add the script to the mesh you want to manipulate. Select the mesh in the scene list and, in the Inspector tab, search for Mesh Smoother.

Inspector Tab
Inspector Tab

To make the mesh smoother, you must tweak the options in the script.

Subdivision Level [0-10]: The level in which the triangles of the mesh will be subdivided in smaller triangles.

Times to Subdivide [0-10]: How many times to repeat the process of subdivision using the above Subdivision Level.

Mesh Smoother options
Mesh Smoother options

If you are going to modify the shape of the mesh during runtime, it’s recommended that you keep a low subdivision level and repeat the subdivision more times, as it will be less resourceful (and will achieve a higher FPS rate).


This article was written based on the project Unity Robot Teleoperation .

Thanks to Lucas C. Figueiredo and Luciano C. A. Pimenta for making this project possible.

ITALO LELIS

I'm a tech enthusiast who loves to explore new solutions to old problems and who codes for fun!

Software Developer

Belo Horizonte-MG, Brazil

Follow me:
Learn More >