GPU数据处理全过程:从积木拼接到像素上色

这篇文章通过建筑工地的比喻,生动解释了GPU渲染流程。CPU像设计师,将顶点数据(积木)和索引数据(说明书)发送到GPU显存(仓库)。GPU工人根据索引找到顶点,经顶点着色器(工头)处理,拼成三角形(墙),再通过片元着色器(画匠)上色。代码示例展示了OpenGL中如何上传数据、设置着色器和发起绘制命令。整个过程自动高效,GPU负责从数据处理到最终显示的完整渲染流程。


一、形象比喻

1. 你是建筑设计师,GPU是工地上的工人

你(CPU)把“积木清单”(顶点数据)和“拼装说明书”(索引数据)快递到工地仓库(GPU显存)。

工人(GPU)拿到这些资料后,开始按照说明书拼房子(渲染图形)。

2. 施工流程

工人先看说明书(索引),找到需要的积木(顶点)。

每块积木都要经过工头(顶点着色器)检查、加工(比如变换位置)。

工人把三块积木拼成一面墙(三角形)。

画匠(片元着色器)给墙上色、贴砖(纹理)。

最后,房子建好,展示给大家看(显示到屏幕)。


二、代码实现(以OpenGL为例)

我们用一个简单的三角形为例,展示GPU收到数据后是怎么一步步用起来的。

1. 上传数据到GPU(准备阶段)

// 顶点数据:三角形的三个点
float vertices[] = {
    // 位置        // 颜色
     0.0f, 0.5f,   1.0f, 0.0f, 0.0f, // 顶点1:红色
    -0.5f,-0.5f,   0.0f, 1.0f, 0.0f, // 顶点2:绿色
     0.5f,-0.5f,   0.0f, 0.0f, 1.0f  // 顶点3:蓝色
};
unsigned int indices[] = { 0, 1, 2 }; // 三角形

// 创建并上传到GPU
GLuint vbo, vao, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);

glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

// 设置顶点属性指针
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // 位置
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float))); // 颜色
glEnableVertexAttribArray(1);

glBindVertexArray(0);

2. GPU怎么用这些数据?(渲染阶段)

2.1 你发出“开工”命令

glUseProgram(shaderProgram); // 使用着色器
glBindVertexArray(vao);      // 绑定VAO
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); // 画三角形

2.2 GPU内部流程(自动完成)

拿说明书(索引):GPU读indices,知道要用第0、1、2号顶点。

找积木(顶点):GPU去vertices里找对应数据。

工头加工(顶点着色器):每个顶点送进顶点着色器,做变换、传递颜色。

拼三角形:GPU把三个顶点拼成一个三角形。

画匠上色(片元着色器):三角形覆盖的每个像素都执行片元着色器,决定颜色。

展示成果:最终像素写入帧缓冲,显示到屏幕。

2.3 着色器代码(工头和画匠)

顶点着色器(工头)

#version 330 core
layout(location = 0) in vec2 aPos;    // 位置
layout(location = 1) in vec3 aColor;  // 颜色
out vec3 ourColor;                    // 传给片元着色器

void main()
{
    gl_Position = vec4(aPos, 0.0, 1.0); // 变换到屏幕坐标
    ourColor = aColor;                  // 传递颜色
}

片元着色器(画匠)

#version 330 core
in vec3 ourColor;      // 从顶点着色器来的颜色
out vec4 FragColor;    // 输出到屏幕

void main()
{
    FragColor = vec4(ourColor, 1.0); // 上色
}

三、流程串联

你上传数据 → GPU仓库有了积木和说明书。

你发指令(DrawCall) → 工人开始施工。

GPU按说明书找积木 → 每块积木送工头加工。

拼三角形 → 画匠给每块墙上色。

成果展示 → 房子建好,大家看到。


四、总结

GPU收到数据后怎么用?

就是根据索引,找顶点,送进着色器加工,拼成三角形,给每个像素上色,最后显示到屏幕。

代码实现

你只需上传数据、写好着色器、发起DrawCall,剩下的拼装和上色,GPU全自动高效完成!


版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33060405/article/details/148294626

最新文章