Skip to content

第十一章 · 顶点着色器 (GLSL)

11.1 GLSL 基础

glsl
#version 450

// 入口点
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;

// Uniform 缓冲区
layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;

// 输出到片元着色器
out vec3 vColor;

void main() {
    gl_Position = ubo.proj * ubo.view * ubo.model * vec4(aPos, 1.0);
    vColor = aColor;
}

11.2 顶点着色器管线

输入 (Input) → 处理 → 输出 (Output)
    ↓              ↓          ↓
aPos, aColor   mat4 计算   vColor, gl_Position

11.3 Uniform 缓冲区对象(UBO)

glsl
// Shader 中的 UBO 定义
layout(binding = 0) uniform UniformBufferObject {
    mat4 model;      // 4x4 = 64 bytes
    mat4 view;       // 4x4 = 64 bytes
    mat4 proj;       // 4x4 = 64 bytes
} ubo;

// 注意: mat4 必须按 256-byte 对齐
// struct padding 很重要!

// 正确的对齐写法:
struct UniformBufferObject {
    mat4 model;      // offset 0, size 64 (实际占 256)
    mat4 view;       // offset 256
    mat4 proj;       // offset 512
    // padding: 192 bytes
};                   // total: 768 bytes (必须是 256 的倍数)

11.3.1 对齐规则

类型对齐大小
float / int44 bytes
vec288 bytes
vec31616 bytes
vec41616 bytes
mat21632 bytes (column-major)
mat31664 bytes
mat4256256 bytes (column-major)

11.4 顶点属性 (Layout)

glsl
// 输入属性
layout(location = 0) in vec3 aPos;     // 位置 (3 floats)
layout(location = 1) in vec3 aColor;   // 颜色 (3 floats)
layout(location = 2) in vec2 aTexCoord; // UV 坐标 (2 floats)

// 输出到片元
out vec3 vColor;
out vec2 vTexCoord;
out vec4 vPosition;

11.5 矩阵计算

glsl
// 列主序矩阵乘法: gl_Position = proj × view × model × position
gl_Position = proj * view * model * vec4(aPos, 1.0);

// 如果只需要旋转+平移(无缩放)
mat4 transform = mat4(aMat3, 0.0) + vec4(aTranslation, 0.0);
gl_Position = proj * view * transform * vec4(aPos, 1.0);

11.6 内置变量

变量说明
gl_Position裁剪空间位置(输出)
gl_PointSize点大小(gl.POINT_LIST)
gl_ClipDistance自定义裁剪
gl_PrimitiveID图元 ID(内置输入)
gl_InstanceID实例 ID(内置输入)
gl_VertexID顶点 ID(内置输入)