OpenGL/C++ 学习笔记(二) 图形渲染相关概念

汇总页
上一篇: OpenGL / C++ 学习笔记(一) 搭设环境


OpenGL/C++ 学习笔记(二) 引入图形渲染相关概念

  • OpenGL/C++ 学习笔记
    • 图形渲染流程相关概念
      • 渲染管线
      • 其他常用名词
    • 画面渲染流水线
      • 顶点着色器VS
      • 片元着色器FS
      • 其他一些在渲染流程中非必须的着色器
        • 细分着色器
        • 几何着色器GS

OpenGL/C++ 学习笔记

图形渲染流程相关概念

渲染管线

pipeline, 中文意为管线, 实话说这个词在中文语境下不太直观, 其实际意义等同于流水线. 在gpu参与的画面渲染流程中, 渲染管线(rendering pipeline)将指明渲染一个画面需要经过何种以及多少道工序. 通常体现为多阶段各层面的像素着色程序(均使用glsl语言编写, OpenGL Shader Language, 语法类似C语言).

猴子也能看懂的渲染管线(Render Pipeline)

OpenGL/C++ 学习笔记(二) 图形渲染相关概念_第1张图片

流水线流程简述: 由用户设计的gl应用通过gl库的函数接口向gpu提交所需要渲染的图形模型的顶点信息、纹理信息等, 依次经由顶点着色器, 细分着色器, 几何着色器, 片元着色器等的处理之后得到结果输出显示到显示设备上.

其他常用名词

  • 顶点(vertexs): 组成模型各线和面的原始顶点集合.
  • 图元(primitives): 一个图元即是一部分顶点的有序集合, 在空间中以点线面的客观形式体现出来.
  • 矢量和栅格: 这个在绘画行业应该是经常接触的概念, 矢量图可以无限制放大缩小但不会导致失真, 但是其存储与显示前运算成本高于栅格化的图像(直接搜索查看栅格就能理解栅格在显示渲染层面上的含义了吧, 或者再将其与方格调色板或者化妆盘类比).
  • 光栅化: 图元是三维连续空间中的几何概念, 而显示设备是间断的以整数表示像素坐标的平面空间, 光栅化负责将连续空间中的图元信息映射到像素平面空间(超采样/抗锯齿或许就是在这个阶段完成的? 待考证).
  • 片元(fragments, 又叫片段): 连续空间中的点, 线段或多边形投射到间断的像素平面中得到的最小信息单元. 是在图元光栅化后, 被映射成一个个像素大小的基本单位.
    片元其实已经很接近像素了, 但是它还不是像素 – 片元包含了比RGBA更多的信息, 比如可能有深度值, 法线, 纹理坐标等等信息.
  • 像素(pixels): 绘制窗口上的真实像素点, 只有得到最终渲染结果所需的色彩信息.
    片元需要在通过一些测试(如深度测试)后才会最终成为像素. 可能会有多个片元竞争同一个像素, 而这些测试会最终筛选出一个合适的片元, 丢弃法线和纹理坐标等不需要的信息后, 成为渲染到像素屏幕上的最终结果, 即像素.

画面渲染流水线

顶点着色器VS

负责处理cpu向gpu提交的原始顶点数据.

  1. 在顶点着色器工作之前, 需要由cpu应用代码完成以下工作: ①读取并编译着色器; ②向显卡申请显存空间; ③用数组通过gl库api向为其开辟的定长显存提供原始顶点信息, 在opengl中以VAO形式记录(vertex Array object, 顶点缓存对象).
  2. 在渲染时, 渲染管线从显存中取出顶点数据(显存划分方式的凭据是cpu在申请显存空间时提供的缓存长度和数据类型, 类比c语言中的malloc所获得的内存的使用方式), 以in标识的变量的形式传入顶点着色器, 依据应用程序编译提供的着色器脚本对其进行处理.
  3. 对数据进行处理后存入out修饰符修饰的变量(可以是结构体)中, 传递给后续着色器(通常为片元着色器).

顶点着色器代码示例(详尽功能与使用方法将在后续文章中详细介绍)

// 着色器版本号指定, 若缺省则默认版本号110, core表示使用OpenGL核心模式, 此处的内容需要和应用程序中的一致
#version 330 core

// 应用程序通过gl函数传入的原始数据(名称和类型数量均自定义, 用in修饰)
// 限定符 layout (location = x) 中的x与应用中的glVertexAttribPointer函数第一个参数所对应输入标记一致
layout (location = 0) in vec3 aPos;         // 局部/物体空间坐标
layout (location = 1) in vec2 aTexCoord;    // 纹理坐标
layout (location = 2) in vec3 modelIntance; // 世界空间坐标

// out修饰的输出结构体
out vertex_info{
    vec3 normal;        // 法线方向
    vec2 TexCoord;      // 纹理信息
} vertex;

// uniform 限定符, 应用程序函数调用时通过一致的变量名进行数据传入
// 用于空间变换的矩阵, 视野与投影
uniform mat4 view;
uniform mat4 projection;

void main(){
    vertex.TexCoord = vec2(aTexCoord.x, aTexCoord.y);

    // gl_Position是顶点着色器默认输出变量
    // 在几何阶段最后一个着色器中经过视角与投影处理裁剪后交付给光栅化阶段
    gl_Position = projection * view * vec4 (modelIntance + aPos, 1.0f);
}

片元着色器FS

负责处理光栅化后所得片元, 基于cpu向gpu提供的顶点组织形式(默认三角顶点面, 摄像头视野内面为顺时针则表示面朝向屏幕)

片元着色器代码示例

#version 330 core

// 输出的片元颜色数据(四色彩通道)
out vec4 FragColor;

// 传入数据的结构体, 此处承接上文顶点着色器示例
in vertex_info{
    vec3 normal;
    vec2 TexCoord;
} vertex;

// 2d纹理对象
uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, vertex.TexCoord);  // 对纹理指定位置进行色彩采样
}

其他一些在渲染流程中非必须的着色器

在渲染流程中存在一些非必须的着色器, 若渲染前着色器程序未编译链接对应着色器脚本则不会被激活/参与到渲染流程中.
这个部分暂时还没深入学习, 仅了解了基础概念, 因此不在此详细记录

细分着色器

对顶点着色器产生的图元插入顶点, 进行细分, 从而产生更多的图元.
细分着色器有两个着色阶段: 细分控制着色器,细分计算着色器.

  1. 首先要指定面片 也就是顶点的有序列表;
  2. 渲染面片时 将首先执行细分控制着色器,处理面片顶点,并设置面片中要生成多少集合数据;
  3. 细分控制着色器结束后 细分计算着色器将负责把生成网格的顶点放置到细分坐标指定的位置 并将他们发送到光栅化阶段 或发给几何着色器;
几何着色器GS

与顶点着色器输入的都是单个顶点不同,几何着色器的输入为单个基础图元, 每次执行时获得图元的全部顶点信息.


下一篇: OpenGL / C++ 学习笔记(三) 绘制第一个图形

你可能感兴趣的:(OpenGL入门笔记,c++,学习,笔记,图形渲染)