+6 votes

I would like to know how to generate a 3D mesh from code in Godot. I would like to be able to supply a list of vertices, triangles, UVs, etc, and turn this into a Mesh.

In Unity, I can generate custom meshes by using Vector3[] of vertices, Vector2[] of UVs,List<Mesh>, MeshFilter, and CombineInstance. There are many tutorials on how to do this in Unity.

I am using C# but answers in GDscript would also be useful and appreciated (I would expect GDscript answers to be easily translatable to C#)

in Engine by

2 Answers

+6 votes

The following code (in GDscript) will apply the generated mesh (a red plane) to a child MeshInstance node named "MeshInstance"

var tmpMesh = Mesh.new()
var vertices = PoolVector3Array()
var UVs = PoolVector2Array()
var mat = SpatialMaterial.new()
var color = Color(0.9, 0.1, 0.1)

func _ready():

    vertices.push_back(Vector3(1,0,0))
    vertices.push_back(Vector3(1,0,1))
    vertices.push_back(Vector3(0,0,1))
    vertices.push_back(Vector3(0,0,0))

    UVs.push_back(Vector2(0,0))
    UVs.push_back(Vector2(0,1))
    UVs.push_back(Vector2(1,1))
    UVs.push_back(Vector2(1,0))

    mat.albedo_color = color

    var st = SurfaceTool.new()
    st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN)
    st.set_material(mat)

    for v in vertices.size(): 
        st.add_color(color)
        st.add_uv(UVs[v])
        st.add_vertex(vertices[v])

    st.commit(tmpMesh)

    $MeshInstance.mesh = tmpMesh

It used a Triangle Fan but there are other ways to create your mesh from vertices depending on what order/format you have them stored in. Take a look at the enum PrimitiveTypes on the Mesh page to see your other options.

by (252 points)
edited by

using that code doesn't show anything. I am using 3.1.1
No errors
No 3D mesh appearing in the scene

Did you create a MeshInstance node named "MeshInstance" and is the script adding a mesh to it at runtime? Did you add your MeshInstance to the scene tree?

When I try it my plane is black with no color :O

And when I edit the size of the plane, lets say from 1 to 5, do I need to adjust the UVs?

Did you create a MeshInstance node named "MeshInstance" and is the script adding a mesh to it at runtime? Did you add your MeshInstance to the scene tree? 

yes i did all that. that was 3 days ago and i already got another solution ty

How did you fix it? Can you share the solution? :)

I had the same problem. I just have added a Camera node with the following parameters under Spatial > Transform :

  • Translation : 0, 1, 0
  • Rotation : -90, 0, 0
+1 vote

You can use SurfaceTool. Simple mehs terrain generator example:

https://github.com/barrrettt/GeneratedMesh-Godot-Cs

private SurfaceTool createQuad(SurfaceTool st, Vector3 pos, Quat q){

//1Quad = 4 points = 2 triangles
Vector3 v1 = new Vector3(0, q.x,-1) + pos;
Vector3 v2 = new Vector3(1, q.y,-1) + pos;
Vector3 v3 = new Vector3(1, q.w, 0) + pos;
Vector3 v4 = new Vector3(0, q.z,0) + pos;

//tri1
st.AddUv(new Vector2(0,0));
st.AddColor(heightToColor(v1.y));// active albedoVertexColors
st.AddVertex(v1);


st.AddUv(new Vector2(0,1));
st.AddColor(heightToColor(v2.y));
st.AddVertex(v2);


st.AddUv(new Vector2(1,1));
st.AddColor(heightToColor(v4.y));
st.AddVertex(v4);

//tri2
st.AddUv(new Vector2(0,0));
st.AddColor(heightToColor(v2.y));
st.AddVertex(v2);

st.AddUv(new Vector2(0,1));
st.AddColor(heightToColor(v3.y));
st.AddVertex(v3);

st.AddUv(new Vector2(1,1));
st.AddColor(heightToColor(v4.y));
st.AddVertex(v4);

return st;

}

by (48 points)

Watched this video before but forgot about it. I can't create a mesh. I tried it on the internet, but it just isn't visible.

extends Node2D

var tmpMesh = Mesh.new()
var vertices = PoolVector3Array()
var UVs = PoolVector2Array()
var mat = SpatialMaterial.new()
var color = Color(0.9, 0.1, 0.1)

func _ready():

    vertices.push_back(Vector3(1,0,0))
    vertices.push_back(Vector3(1,0,1))
    vertices.push_back(Vector3(0,0,1))
    vertices.push_back(Vector3(0,0,0))

    UVs.push_back(Vector2(0,0))
    UVs.push_back(Vector2(0,1))
    UVs.push_back(Vector2(1,1))
    UVs.push_back(Vector2(1,0))

    mat.albedo_color = color

    var st = SurfaceTool.new()
    st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN)
    st.set_material(mat)

    for v in vertices.size(): 
        st.add_color(color)
        st.add_uv(UVs[v])
        st.add_vertex(vertices[v])

    st.commit(tmpMesh)

    $MeshInstance2D.mesh = tmpMesh

I tried to do it in 2D at first, because I thought that I was pointing the camera in the wrong direction.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.