着色器管线

  flowchart LR
	c1["CPU"] --> s1["顶点着色器"]
	subgraph x["细分着色器"]
		s2["细分控制着色器"] --> s3["细分验证着色器"]
	end
	s1 --> s2
	s3 --> s4["几何着色器"] --> s5["片段着色器"] --> c2["帧缓冲区"]

顶点着色器 Vertex Shader

顶点着色器是 OpenGL 着色器管线的第一个阶段,负责处理每个输入顶点的数据。

GLSL
#version 460 core

/* ① 输入数据 */
layout (location = 0) in vec3 aPos; // 顶点位置
layout (location = 1) in vec3 aNormal; // 顶点法线
layout (location = 2) in vec2 aTexCoord; // 纹理坐标

/* ② 输出数据 */
layout (location = 0) out vec2 TexCoord;
layout (location = 1) out vec3 FragPos;
layout (location = 2) out vec3 Normal;

/* ③ Uniform */
layout (location = 0) uniform mat4 Transform;

void main() {
	/* ④ gl_Position */
    gl_Position = Transform * vec4(Position, 1.0);

	/* ② 输出数据 */
	TexCoord = aTexCoord; // 传递纹理坐标
    FragPos = vec3(model * vec4(aPos, 1.0)); // 计算顶点的世界坐标并传递
    Normal = mat3(transpose(inverse(model))) * aNormal; // 计算法线变换并传递
}
点击展开查看更多

片段着色器 Fragment Shader

片段着色器是 OpenGL 着色器管线的最后一个阶段,负责计算每个片段(像素)的最终颜色。

GLSL
#version 460 core

/* ① 输入数据 */
layout (location = 0) in vec2 TexCoord;
layout (location = 1) in vec3 FragPos;
layout (location = 2) in vec3 Normal;

/* ② 输出数据 */
layout (location = 0) out vec4 FragColor;
// layout (location = 1) out vec4 OtherColor;

/* ③ Uniform */
layout (location = 0) uniform vec4 SomeUniform;

void main() {
    FragColor = vec4(1.0);
}
点击展开查看更多

① 输入数据

GLSL
[layout (location = x)] in [插值类型] 变量类型 名称;
点击展开查看更多

顶点 着色器阶段

顶点着色器的in变量的数据由CPU程序直接传入,可以通过变量索引变量名进行数据传递。

该阶段插值类型无意义

其他 着色器阶段

其他着色器的in变量的数据由上阶段着色器的out变量传入,要求对应变量的变量索引变量名插值类型必须一致才能够匹配并传递。

② 输出数据

GLSL
[layout (location = x)] out [插值类型] 变量类型 名称;
点击展开查看更多

其他 着色器阶段

out变量会向下一阶段的着色器传递。

片段 着色器阶段

片段着色器的out变量会直接写入 帧缓冲区(Frame Buffer)的指定颜色附件(Color Attachment),可以输出多个vec4变量到多个颜色附件。

③ Uniform

GLSL
[layout (location = x)] uniform 变量类型 名称;
点击展开查看更多

Uniform变量的数据均由CPU程序直接传入,常用作动态调节的着色器参数。

⊙变量索引 和 插值符

④ gl_Position

gl_Position 是顶点着色器的 唯一必须输出,用于存储当前顶点在 齐次裁剪空间 中的坐标。注意该变量类型为vec4

版权声明

作者: Chaim

链接: https://chaim.eu.org/posts/%E7%9D%80%E8%89%B2%E5%99%A8%E5%9F%BA%E7%A1%80/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键