Trong Cocos Creator 3, Shader không thể trực tiếp gán vào model 3D mà bắt buộc phải thông qua Material (Vật liệu). Quy trình thiết lập cốt lõi bao gồm: Tạo một Material mới, chọn file .effect (Shader tùy chỉnh) tại thuộc tính Effect, sau đó gán Material này vào mảng Materials của component MeshRenderer trên node model.
Khối CCEffect: Cấu hình quy trình Render
File .effect sử dụng cú pháp YAML để khai báo các kỹ thuật render và thuộc tính. Đây là cầu nối giúp các biến trong Shader có thể được tinh chỉnh trực tiếp trên giao diện Cocos Creator Editor.
CCEffect %{
techniques:
- name: custom-opaque
passes:
- vert: vs:main
frag: fs:main
properties:
baseTexture: { value: grey }
tintStrength: { value: [1.0, 1.0, 1.0], target: colorParams.xyz }
depthStencilState:
depthTest: true
depthWrite: true
}%
Cấu trúc trên định nghĩa một kỹ thuật render không xuyên thấu (opaque). Trong passes, chúng ta trỏ tới các hàm entry của Vertex Shader (vs:main) và Fragment Shader (fs:main). Khối properties ánh xạ dữ liệu vào các biến uniform tương ứng bên trong mã nguồn GLSL.
Khối CCProgram: Mã nguồn GLSL
Đây là phần lõi chứa thuật toán xử lý đồ họa. Một template cơ bản bao gồm khai báo độ chính xác, các thư viện macro dựng sẵn và hàm main.
CCProgram shader-module %{
precision highp float;
#include <legacy/output>
#include <legacy/fog-fs>
uniform FragmentConstants {
vec4 colorParams;
};
vec4 main() {
vec4 finalColor = vec4(1.0);
// Thuật toán xử lý màu sắc
return CCFragOutput(finalColor);
}
}%
Thực hành: Shader chuyển màu Gradient
Dưới đây là một ví dụ hoàn chỉnh về Fragment Shader tạo hiệu ứng chuyển màu từ trái sang phải dựa trên tọa độ UV, đồng thời kết hợp với màu sắc từ texture gốc. Các biến và logic đã được tái cấu trúc để tối ưu hóa việc đọc hiểu.
CCEffect %{
techniques:
- name: gradient-tech
passes:
- vert: general-vs:vert
frag: custom-gradient-fs:frag
properties:
albedoMap: { value: white }
startTint: { value: [0.2, 0.5, 0.8, 1.0], editor: { type: color } }
endTint: { value: [0.9, 0.2, 0.2, 1.0], editor: { type: color } }
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
}%
CCProgram custom-gradient-fs %{
precision highp float;
#include <legacy/output>
#include <legacy/fog-fs>
in vec2 v_uv;
in vec3 v_worldPos;
uniform sampler2D albedoMap;
uniform GradientData {
vec4 startTint;
vec4 endTint;
};
vec4 frag () {
// Lấy màu cơ bản từ texture
vec4 texColor = texture(albedoMap, v_uv);
// Tính toán hệ số nội suy dựa trên trục X của UV
float lerpFactor = v_uv.x;
// Trộn màu giữa điểm đầu và điểm cuối
vec4 gradientColor = mix(startTint, endTint, lerpFactor);
// Nhân màu texture với dải màu gradient
vec4 finalColor = texColor * gradientColor;
// Áp dụng hiệu ứng sương mù theo khoảng cách
CC_APPLY_FOG(finalColor, v_worldPos);
// Xuất màu cuối cùng ra pipeline render
return CCFragOutput(finalColor);
}
}%
Sau khi lưu file .effect, tiến hành tạo Material mới trỏ đến file này và gán vào component MeshRenderer của model, dải màu gradient sẽ được render tự động theo trục X của bề mặt vật thể.