Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
使用 SurfaceTool¶
SurfaceTool 提供了一個有用的介面來建構幾何體。這個介面類別似於 ImmediateGeometry 節點。你設定每個頂點的屬性(例如法線、uv、顏色),然後當你新增一個頂點時,它就會捕捉到這些屬性。
SurfaceTool 還提供了一些有用的輔助函式,如 index()
和 generate_normals()
。
屬性是在新增每個頂點之前新增的:
st.set_normal() # Overwritten by normal below.
st.set_normal() # Added to next vertex.
st.set_color() # Added to next vertex.
st.add_vertex() # Captures normal and color above.
st.set_normal() # Normal never added to a vertex.
st.SetNormal(); // Overwritten by normal below.
st.SetNormal(); // Added to next vertex.
st.SetColor(); // Added to next vertex.
st.AddVertex(); // Captures normal and color above.
st.SetNormal(); // Normal never added to a vertex.
當使用 SurfaceTool 完成生成幾何體後,呼叫 commit()
完成生成網格。如果將一個 ArrayMesh 傳遞給了 commit()
,那麼它就會在這個 ArrayMesh 的末尾附加一個新的表面。而如果沒有傳遞任何資訊,commit()
則返回一個 ArrayMesh。
st.commit(mesh)
# Or:
var mesh = st.commit()
st.Commit(mesh);
// Or:
var mesh = st.Commit();
程式碼建立一個有索引的三角形
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
st.add_vertex(Vector3(-1, -1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 1))
st.add_vertex(Vector3(-1, 1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(1, 1))
st.add_vertex(Vector3(1, 1, 0))
# Commit to a mesh.
var mesh = st.commit()
var st = new SurfaceTool();
st.Begin(Mesh.PrimitiveType.Triangles);
// Prepare attributes for AddVertex.
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 0));
// Call last for each vertex, adds the above attributes.
st.AddVertex(new Vector3(-1, -1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 1));
st.AddVertex(new Vector3(-1, 1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(1, 1));
st.AddVertex(new Vector3(1, 1, 0));
// Commit to a mesh.
var mesh = st.Commit();
你可以選擇新增一個索引陣列, 可以通過呼叫 add_index()
將頂點新增到索引陣列中, 也可以通過呼叫 index()
將頂點陣列縮小以刪除重複的頂點.
# Creates a quad from four corner vertices.
# add_index does not need to be called before add_vertex.
st.add_index(0)
st.add_index(1)
st.add_index(2)
st.add_index(1)
st.add_index(3)
st.add_index(2)
# Alternatively:
st.index()
// Creates a quad from four corner vertices.
// AddIndex does not need to be called before AddVertex.
st.AddIndex(0);
st.AddIndex(1);
st.AddIndex(2);
st.AddIndex(1);
st.AddIndex(3);
st.AddIndex(2);
// Alternatively:
st.Index();
同樣, 如果你有一個索引陣列, 但希望每個頂點都是唯一的(例如, 因為想在每個面而不是每個頂點使用唯一的法線或顏色), 可以呼叫 deindex()
.
st.deindex()
st.Deindex();
如果你不想自行新增自訂法線,那麼可以使用 generate_normals()
來新增,呼叫時機應該是在生成幾何體之後、使用 commit()
或 commit_to_arrays()
提交網格之前。呼叫 generate_normals(true)
會將最終的法線翻轉。另外請注意,generate_normals()
只有在像素型別為 Mesh.PRIMITIVE_TRIANGLES
時有效。
你可能發現了,在生成的網格上,法線貼圖或者其他一些材質屬性看上去不對勁。這是因為對法線貼圖而言,**必需**的是*切線*,這和*法線*是兩碼事。有兩種解決方法,手動新增切線資訊,或者使用 generate_tangents()
自動生成。這個方法要求每個頂點都已經具有 UV 和法線。
st.generate_normals()
st.generate_tangents()
st.GenerateNormals();
st.GenerateTangents();
預設情況下, 當生成法線時, 它們將以每個面為基礎進行計算. 如果想要平滑的頂點法線, 在新增頂點時, 呼叫 add_smooth_group()
. add_smooth_group()
需要在建立幾何體時呼叫, 例如在呼叫 add_vertex()
(如果沒有索引)或 add_index()
(如果有索引)之前.