Đổi màu đỉnh là giai đoạn trong đường ống xử lý đồ họa chịu trách nhiệm xử lý dữ liệu của từng đỉnh riêng biệt, thực hiện các phép biến đổi tọa độ, chuyển đổi pháp tuyến, v.v. Đầu vào của nó là các thuộc tính của đỉnh đơn lẻ (như vị trí, pháp tuyến), và đầu ra là dữ liệu đã xử lý để sử dụng ở các giai đoạn sau. Đặc điểm quan trọng bao gồm: xử lý hoàn toàn độc lập cho mỗi đỉnh (không thể truy cập dữ liệu của đỉnh khác) và khả năng song song hóa cao (GPU có thể xử lý hàng nghìn đỉnh cùng một lúc). Ví dụ khi hiển thị một tam giác, đổi màu đỉnh sẽ được gọi 3 lần, mỗi lần xử lý một đỉnh.
Giải Thích Chi Tiết
- Trong đường ống xử lý đồ họa, nhiệm vụ chính của đổi màu đỉnh là xử lý từng đỉnh đầu vào, chẳng hạn như biến đổi tọa độ (không gian mô hình → không gian thế giới → không gian cắt), chuyển đổi pháp tuyến, tính toán màu sắc đỉnh, truyền UV, v.v.
- Đầu vào của đổi màu đỉnh là dữ liệu của từng đỉnh (như vị trí, pháp tuyến, UV, v.v.), và đầu ra là dữ liệu đỉnh đã xử lý (như tọa độ đã biến đổi, dữ liệu nội suy truyền đến đổi màu điểm, v.v.).
- Đổi màu đỉnh không thể truy cập trực tiếp dữ liệu của các đỉnh khác, mỗi đỉnh được xử lý một cách độc lập (tuy nhiên, các giai đoạn sau như đổi màu hình học, đổi màu phân đoạn bề mặt có thể truy cập nhiều đỉnh, nhưng đổi màu đỉnh bản thân chỉ xử lý từng đỉnh).
Ví Dụ Minh Họa
Giả sử có một tam giác với 3 đỉnh. Khi hiển thị, đổi màu đỉnh sẽ được gọi 3 lần, mỗi lần xử lý một đỉnh.// Pseudo-code
for (mỗi đỉnh v)
{
chạy đổi màu đỉnh(v);
}
Đổi màu đỉnh là độc lập đối với mỗi đỉnh và có mức độ song song hóa rất cao, phù hợp cho việc xử lý song song lớn trên GPU.
Tiếp theo, chúng ta sẽ tìm hiểu về cấu trúc đầu vào và đầu ra của đổi màu đỉnh, cũng như mối quan hệ giữa đổi màu đỉnh và đổi màu điểm, thông qua ví dụ cụ thể sử dụng Unity Shader.Một. Cấu Trúc Đầu vào và Đầu ra của Đổi Màu Đỉnh
1. Cấu trúc đầu vào (appdata)
Đầu vào của đổi màu đỉnh thường là các thuộc tính của từng đỉnh, chẳng hạn như:- Vị trí (POSITION)
- Pháp tuyến (NORMAL)
- Tọa độ texture (TEXCOORD0, TEXCOORD1...)
- Màu sắc (COLOR)
- Hướng tiếp xúc (TANGENT)
struct appdata
{
float4 vertex : POSITION; // Vị trí đỉnh
float3 normal : NORMAL; // Pháp tuyến
float2 uv : TEXCOORD0; // Tọa độ texture
float4 color : COLOR; // Màu sắc đỉnh (tùy chọn)
// ... các thuộc tính khác
};
Dữ liệu này được truyền từ CPU đến GPU thông qua Mesh.
2. Cấu trúc đầu ra (v2f)
Đầu ra của đổi màu đỉnh sẽ được truyền đến bộ nội suy (rasterizer) và cuối cùng đến đổi màu điểm. Cấu trúc đầu ra thường bao gồm:- Tọa độ không gian cắt (SV_POSITION): bắt buộc phải có
- Dữ liệu khác cần nội suy đến điểm (như UV, pháp tuyến, màu sắc, v.v.)
struct v2f
{
float4 pos : SV_POSITION; // Tọa độ không gian cắt, bắt buộc
float2 uv : TEXCOORD0; // Truyền UV đến đổi màu điểm
float3 worldNormal : TEXCOORD1; // Pháp tuyến không gian thế giới
float3 worldPos : TEXCOORD2; // Vị trí không gian thế giới
// ... các dữ liệu khác cần nội suy
};
3. Hàm đổi màu đỉnh
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex); // Biến đổi sang không gian cắt
o.uv = v.uv; // Truyền UV
o.worldNormal = UnityObjectToWorldNormal(v.normal); // Chuyển đổi pháp tuyến
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; // Chuyển đổi vị trí
return o;
}
Hai. Mối Quan Hệ Giữa Đổi Màu Đỉnh và Đổi Màu Điểm
1. Luồng Dữ Liệu
- Đổi màu đỉnh xử lý từng đỉnh, đầu ra là một cấu trúc (ví dụ v2f).
- Giai đoạn nội suy, GPU dựa vào hình học tam giác, nội suy từng trường của cấu trúc đầu ra, tạo ra dữ liệu của mỗi pixel (điểm).
- Đổi màu điểm xử lý từng pixel (điểm), đầu vào là cấu trúc v2f đã nội suy.
2. Đầu vào của Đổi Màu Điểm
Cấu trúc đầu vào của đổi màu điểm thường giống với cấu trúc đầu ra của đổi màu đỉnh. Ví dụ:fixed4 frag(v2f i) : SV_Target
{
// i.uv, i.worldNormal, i.worldPos là dữ liệu đã nội suy
// Tại đây có thể lấy mẫu từ texture, làm ánh sáng, v.v.
}
3. Tổng Kết Mối Quan Hệ
- Nếu đổi màu đỉnh đầu ra gì, đổi màu điểm sẽ nhận được (đã nội suy).
- Đổi màu điểm không thể truy cập trực tiếp dữ liệu của đỉnh, chỉ có thể truy cập dữ liệu đã nội suy.
- Nếu bạn muốn sử dụng dữ liệu nào đó trong đổi màu điểm, hãy đảm bảo rằng nó được truyền qua cấu trúc đầu ra của đổi màu đỉnh.
Ba. Ví Dụ Hoàn Chỉnh
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
};
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// i.uv là tọa độ texture đã nội suy
// i.worldNormal là pháp tuyến đã nội suy
// Tại đây có thể lấy mẫu từ texture, làm ánh sáng, v.v.
return fixed4(i.uv, 0, 1);
}
Bốn. Bản Thảo (Luồng Dữ Liệu)
[Dữ liệu Đỉnh Mesh]
↓
[Đổi màu đỉnh] (mỗi đỉnh)
↓
[Nội suy/Bộ cắt] (nội suy bên trong tam giác)
↓
[Đổi màu điểm] (mỗi pixel/điểm)
Năm. Tổng Kết
- Đầu vào của đổi màu đỉnh là các thuộc tính của đỉnh đơn lẻ, đầu ra là cấu trúc tùy chỉnh.
- Đầu vào của đổi màu điểm là cấu trúc đã nội suy, nguồn gốc từ đầu ra của đổi màu đỉnh.
- Nếu bạn muốn đổi màu điểm sử dụng dữ liệu nào đó, hãy đảm bảo rằng nó được truyền qua cấu trúc đầu ra của đổi màu đỉnh.