[英]Set color for each vertex in a triangle
我想從網格紅色、藍色和綠色中設置三角形的每個三個頂點。
如本教程的第一部分所示,它適用於另一種語言。 這是他們用來為網格中每個三角形中的每個頂點設置紅色、綠色和藍色的代碼:
function set_wireframe_colors(m)
local cc = {}
for i = 1, m.size/3 do
table.insert(cc, color(255,0,0))
table.insert(cc, color(0,255,0))
table.insert(cc, color(0,0,255))
end
m.colors = cc
end
這就是 output 使用簡單的頂點顏色着色器后的樣子:
我試圖在 Unity 中使用 C# 重新創建相同的東西,但我在學習本教程的第一部分時遇到了困難。
這是我的代碼:
void Start()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
//Create new colors array where the colors will be created.
Color32[] colors = new Color32[vertices.Length];
for (int i = 0; i < vertices.Length; i += 3)
{
colors[i] = new Color32(255, 0, 0, 255);
colors[i + 1] = new Color32(0, 255, 0, 255);
colors[i + 2] = new Color32(0, 0, 255, 255);
}
//assign the array of colors to the Mesh.
mesh.colors32 = colors;
}
但這是我從 Unity 獲得的帶有簡單頂點顏色着色器的 output:
如果你仔細觀察,你會發現我的立方體中的每個頂點都沒有分配給它的 rgb 顏色,就像我的第一個屏幕截圖中的立方體一樣。 雖然它看起來非常接近。
代碼有什么問題? 為什么每個頂點不像我的第一個屏幕截圖中的圖像那樣具有 rgb 顏色。
着色器:
這個問題可能與着色器無關,但這里是 Unity 中的簡單顏色着色器:
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
float4 frag(v2f i) : SV_Target
{
return i.color;
}
他使用的網格每個三角形有3個獨立的頂點(每個四邊形6個頂點)。 在統一立方體中,每個面是具有4個頂點的四邊形,並且每個面上的2個三角形共享2個頂點。
左邊是一個四邊形,有四個頂點, mesh.triangles
數組是0 1 2 1 0 3
,右邊是一個四邊形,有6個頂點,帶有mesh.triangles
= 0 1 2 3 4 5
(頂點順序很重要)對於背面剔除。在我的着色器中,我將Cull設置為關閉)。
因此,您可以在圖像中看到此着色器,您可以使用由4個頂點四邊形組成的網格,只要您小心並確保每個三角形在每個頂點中都有一種顏色。
正如我在評論中所說,您可以拆分網格,以便每個三角形有3個唯一的頂點。
void Start () {
Mesh mesh = GetComponent<MeshFilter>().mesh;
SplitMesh(mesh);
SetColors(mesh);
}
void SplitMesh(Mesh mesh)
{
int[] triangles = mesh.triangles;
Vector3[] verts = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector2[] uvs = mesh.uv;
Vector3[] newVerts;
Vector3[] newNormals;
Vector2[] newUvs;
int n = triangles.Length;
newVerts = new Vector3[n];
newNormals = new Vector3[n];
newUvs = new Vector2[n];
for(int i = 0; i < n; i++)
{
newVerts[i] = verts[triangles[i]];
newNormals[i] = normals[triangles[i]];
if (uvs.Length > 0)
{
newUvs[i] = uvs[triangles[i]];
}
triangles[i] = i;
}
mesh.vertices = newVerts;
mesh.normals = newNormals;
mesh.uv = newUvs;
mesh.triangles = triangles;
}
void SetColors(Mesh mesh)
{
Color[] colors = new Color[mesh.vertexCount];
for (int i = 0; i < colors.Length; i+=3)
{
colors[i] = Color.red;
colors[i + 1] = Color.green;
colors[i + 2] = Color.blue;
}
mesh.colors = colors;
}
這不是一個非常優雅的解決方案,但這對我有用。
Mesh newMesh = newObject.GetComponent<MeshFilter>().mesh = mesh;
Vector3[] vertices = newMesh.vertices;
Vector3[] normals = newMesh.normals;
int[] triangles = newMesh.triangles;
var newVertices = new Vector3[triangles.Length];
var newNormals = new Vector3[triangles.Length];
var newTriangles = new int[triangles.Length];
for (var i = 0; i < triangles.Length; i++)
{
newVertices[i] = vertices[triangles[i]];
newNormals[i] = normals[triangles[i]];
newTriangles[i] = i;
}
newMesh.vertices = newVertices;
newMesh.normals = newNormals;
newMesh.triangles = newTriangles;
Color[] colors = new Color[newVertices.Length];
for (int i = 0; i < newVertices.Length-5; i++)
{
float r = UnityEngine.Random.value;
float g = UnityEngine.Random.value;
float b = UnityEngine.Random.value;
if (i % 6 == 0)
{
colors[i] = new Color(r, g, b, 1f);
colors[i + 1] = new Color(r, g, b, 1f);
colors[i + 2] = new Color(r, g, b, 1f);
r = UnityEngine.Random.value;
g = UnityEngine.Random.value;
b = UnityEngine.Random.value;
colors[i + 3] = new Color(r, g, b, 1f);
colors[i + 4] = new Color(r, g, b, 1f);
colors[i + 5] = new Color(r, g, b, 1f);
}
}
newMesh.colors = colors;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.