跳转到主要内容

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

demi 提交于

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

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>一、形象比喻</strong></font>

<font style="line-height: 40px;"><strong>1. 你是建筑设计师,GPU是工地上的工人</strong></font>

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

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

<font style="line-height: 40px;"><strong>2. 施工流程</strong></font>

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

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

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

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

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

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>二、代码实现(以OpenGL为例)</strong></font>

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

<font style="line-height: 40px;"><strong>1. 上传数据到GPU(准备阶段)</strong></font>

<pre>// 顶点数据:三角形的三个点
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);
</pre>

<font style="line-height: 40px;"><strong>2. GPU怎么用这些数据?(渲染阶段)</strong></font>

<strong>2.1 你发出“开工”命令</strong>

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

<strong>2.2 GPU内部流程(自动完成)</strong>

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

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

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

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

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

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

<strong>2.3 着色器代码(工头和画匠)</strong>

顶点着色器(工头)

<pre>#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; // 传递颜色
}
</pre>

片元着色器(画匠)

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

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

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>三、流程串联</strong></font>

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

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

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

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

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

<hr>

<font size="4" style="line-height: 45px;" color="#c200ff"><strong>四、总结</strong></font>

GPU收到数据后怎么用?

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

代码实现

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

<hr>

<font color="#9a9a9a">版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,</font>
<font color="#9a9a9a">遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。</font>
<a href="https://blog.csdn.net/qq_33060405/article/details/148294626"><font color="#9a9a9a">原文链接:https://blog.csdn.net/qq_33060405/article/details/148294626</font></a&gt;
<br>