本教程将通过一个简单的纹理渲染着色器,介绍 ShaderLab 的基础语法结构,通过这个基础示例,你将学会:
ShaderLab 采用三层嵌套结构:Shader
→ SubShader
→ Pass
Shader "Tutorial/01-BasicShader" {
SubShader "Default" {
Pass "Forward" {
// 着色器代码写在这里
}
}
}
在 Pass 中,我们需要声明着色器使用的变量:
// 引擎内置变量:MVP 变换矩阵
mat4 renderer_MVPMat;
// 自定义材质属性
vec4 material_BaseColor; // 基础颜色
sampler2D material_BaseTexture; // 纹理采样器
使用结构体定义顶点数据和传递数据:
// 顶点着色器输入(从网格获取)
struct Attributes {
vec4 POSITION; // 顶点位置
vec2 TEXCOORD_0; // UV 坐标
};
// 顶点着色器输出 / 片元着色器输入
struct Varyings {
vec2 uv; // 传递给片元着色器的 UV 坐标
};
内置顶点属性:
POSITION
:顶点位置TEXCOORD_0
:第一套UV坐标NORMAL
:顶点法线COLOR_0
:顶点颜色指定顶点着色器和片元着色器的入口函数:
VertexShader = vert; // 顶点着色器入口
FragmentShader = frag; // 片元着色器入口
顶点着色器负责处理每个顶点的变换:
Varyings vert(Attributes attr) {
Varyings output;
// MVP 变换:将顶点从模型空间变换到裁剪空间
gl_Position = renderer_MVPMat * attr.POSITION;
// 传递 UV 坐标给片元着色器
output.uv = attr.TEXCOORD_0;
return output;
}
关键点:
gl_Position
是内置输出变量,必须赋值片元着色器负责计算每个像素的颜色:
void frag(Varyings varying) {
// 从纹理中采样颜色
vec4 texColor = texture2D(material_BaseTexture, varying.uv);
// 与材质基础颜色相乘
vec4 finalColor = texColor * material_BaseColor;
// 输出最终颜色
gl_FragColor = finalColor;
}
关键点:
texture2D()
函数用于纹理采样gl_FragColor
是内置输出变量,表示像素最终颜色纹理采样是着色器中的常见操作:
// 声明纹理采样器
sampler2D material_BaseTexture;
// 在片元着色器中采样
vec4 texColor = texture2D(material_BaseTexture, uv);
采样参数:
让我们分析完整的着色器代码:
Shader "Tutorial/01-BasicShader" {
SubShader "Default" {
// Pass 是渲染通道,定义具体的渲染逻辑
Pass "Forward" {
// 引擎内置的 MVP 矩阵,用于顶点变换
mat4 renderer_MVPMat;
// 自定义的材质属性
vec4 material_BaseColor;
sampler2D material_BaseTexture;
// 顶点着色器输入结构体 (Attributes)
struct Attributes {
vec4 POSITION; // 顶点位置
vec2 TEXCOORD_0; // UV 坐标
};
// 顶点着色器输出 / 片元着色器输入结构体 (Varyings)
struct Varyings {
vec2 uv; // 传递给片元着色器的 UV 坐标
};
// 指定着色器入口函数
VertexShader = vert;
FragmentShader = frag;
// 顶点着色器:处理顶点变换和数据传递
Varyings vert(Attributes attr) {
Varyings output;
// 将顶点从模型空间变换到裁剪空间
gl_Position = renderer_MVPMat * attr.POSITION;
// 传递 UV 坐标给片元着色器
output.uv = attr.TEXCOORD_0;
return output;
}
// 片元着色器:计算每个像素的最终颜色
void frag(Varyings varying) {
// 从纹理中采样颜色
vec4 texColor = texture2D(material_BaseTexture, varying.uv);
// 与材质基础颜色相乘
vec4 finalColor = texColor * material_BaseColor;
// 输出最终颜色
gl_FragColor = finalColor;
}
}
}
}
这个着色器会:
前往 游乐场