计算机图形学 | 可编程渲染管线
创始人
2025-06-01 02:43:25
0

计算机图形学 | 可编程渲染管线

  • 计算机图形学 | 可编程渲染管线
    • 3.1 从固定到可编程
      • 图形编程的发展
      • GPU渲染管线
        • 渲染管线的功能
        • 流水线中的三个概念阶段
    • 3.2 探秘GPU渲染管线
      • GPU渲染管线
      • 几何阶段
      • 光栅化阶段
    • 3.3 着色器编程
      • 着色器语言
      • GLSL
      • EBO、VBO和VAO
      • 例程

华中科技大学《计算机图形学》课程

MOOC地址:计算机图形学(HUST)

计算机图形学 | 可编程渲染管线

3.1 从固定到可编程

图形编程的发展

早期的图形编程

在这里插入图片描述

那些用来绘制图元及其属性的对应函数库不存在或非常低级;

不具体硬件相关,不具备可移植性。

程序员有很大的控制权,耗费时间。

图形标准的产生

在这里插入图片描述

  • 图形核心系统(Graphical Kernel System,GKS)
  • 程序员层次式交互图形系统(Programmer’s Hierarchical Interactive Graphics System,PHIGS)
  • 开放的图形库( Open Graphics LibraryOpenGL )

它们都与设备无关。

固定管线

图形API提供了一个对硬件进行操作的标准接口;从内部实现上来说,API对程序员提出的各种绘制图元或属性的请求都采用固定的方式来处理。

这种内部实现方式通常称为固定功能渲染流水线

对程序员来说,控制权减少,非常方便。

典型的光栅扫描图形显示子系统:

在这里插入图片描述

流水线的概念:

在这里插入图片描述

在这里插入图片描述

固定到可编程:钩函数hooks的出现突破固定功能流水线的限制,使用可编程着色器修改流水线中某些特定步骤的行为。

在这里插入图片描述

GPU渲染管线

渲染管线的功能

决定在给定虚拟相机、三维物体、光源、照明模式,以及纹理等诸多条件的情况下生成或绘制一幅二维图像的过程。

在这里插入图片描述

流水线中的三个概念阶段

应用阶段

将需要在屏幕上显示出来绘制的几何体,也就是绘制图元,比如点、线、矩形等输入到绘制管线的下一个阶段。

具体包括图元的顶点数据、摄像机位置、光照纹理等参数。

几何阶段

几何阶段需要将顶点数据最终进行屏幕映射。

这其中需要:

  • 将各个图元放入到世界坐标系中,也就是进行模型变换;
  • 根据光照纹理等计算顶点处材质的光照着色效果;
  • 根据摄像机的位置、取景范围进行观察变换和裁剪;
  • 最后进行屏幕映射,也就是把三维模型转换到屏幕坐标系中

光栅化阶段

光栅化部分的输入是经过变换和投影后的顶点、颜色以及纹理坐标,它的工作是给每个像素正确配色,以便绘制整幅图形。

由于输入的是三角形顶点,所以需要根据三角形表面的差异,逐个遍历三角形计算各个像素的颜色值。之后根据其可见性等进行合并得到最后的输出。

在这里插入图片描述

实例:

在这里插入图片描述

3.2 探秘GPU渲染管线

GPU渲染管线

在这里插入图片描述

几何阶段

在这里插入图片描述

在这里插入图片描述

光栅化阶段

在这里插入图片描述

片元操作:

在这里插入图片描述

3.3 着色器编程

着色器语言

在这里插入图片描述

在这里插入图片描述

Phong光照明模型的综合表述:

由物体表面上一点P反射到视点的光强I为环境光的反射光强、理想漫反射光强和镜面反射光强的总和。

I=IaKa+IpKd(L×N)+IpKs(R×V)nI=I_aK_a+I_pK_d(L×N)+I_pK_s(R×V)^nI=Ia​Ka​+Ip​Kd​(L×N)+Ip​Ks​(R×V)n

在这里插入图片描述

GLSL

OpenGL的着色器语言GLSL,也就是OpenGL Shading Language。

  • 顶点着色器(Vertex Shader)
  • 几何着色器(Geometry Shader)
  • 曲面细分着色器(Tessellation Shader)
  • 片元着色器(Fragment Shader)

在OpenGL中使用着色器的流程:

  1. 创建着色器对象
  2. 源码关联到着色器对象
  3. 编译着色器
  4. 创建一个程序对象
  5. 创建一个程序对象

与OpenGL的通信:

在这里插入图片描述

数据类型:

  • 标量:整数(int)、无符号整数(uint)、布尔类型(bool)及浮点数(float)
  • 矢量:一个矢量可以有2、3、4个分量
  • 矩阵
  • 结构和数组:结构体的成员或者数组的基类型可以为任意的数据类型

控制结构:

  • 循环结构:for、while和do-while
  • 选择结构:if-then、if-then-else,Glsl3.0版本引入了switch结构

EBO、VBO和VAO

EBO(Element Buffer Object,也叫IBO:Index Buffer Object):索引缓冲区对象,这个缓冲区主要用来存储顶点的索引信息。

在这里插入图片描述

VBO(Vertex Buffer Object):顶点缓冲区对象,主要用来存储顶点的各种信息。

好处:模型的顶点信息放进VBO,这样每次画模型时,数据丌用再从CPU的势力范围内存里取,而是直接从GPU的显存里取,从而提高效率。

VAO(Vertex Arrary Object):顶点数组对象

VAO是一个保存了所有顶点数据属性的状态结合,它存储了顶点数据的格式以及顶点数据所需的VBO对象的引用。VAO本身并没有存储顶点的相关属性数据,这些信息是存储在VBO中的,VAO相当于是对很多个VBO的引用,把一些VBO组合在一起作为一个对象统一管理。

VAO和VBO之间的关系:

在这里插入图片描述

例程

方法一:VAO+VBO绘制四边形

// 渲染之前VAO/VBO的绑定生成  
// 顶点数据  
float vertices[] = {  
// 第一个三角形  
0.5f, 0.5f, 0.0f, // 右上  
0.5f, -0.5f, 0.0f, // 右下  
-0.5f, -0.5f, 0.0f, // 左下  
// 第二个三角形  
-0.5f, -0.5f, 0.0f, // 左下  
0.5f, 0.5f, 0.0f, // 右上  
-0.5f, 0.5f, 0.0f // 左上  
};  
// 生成立方体的VAO、VBO  
unsigned int VBO, VAO;  
glGenVertexArrays(1, &VAO);  
glGenBuffers(1, &VBO);  
// 绑定VAO  
glBindVertexArray(VAO);  
// 绑定VBO并传入顶点数据  
glBindBuffer(GL_ARRAY_BUFFER, VBO);  
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  
// 设置顶点属性指针  
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);  
glEnableVertexAttribArray(0);  
// 解绑VBO  
glBindBuffer(GL_ARRAY_BUFFER, 0);  
// 解绑VAO  
glBindVertexArray(0);  
// 渲染时  
// 使用之前链接好的着色器程序  
glUseProgram(shaderProgram);  
// 绑定VAO  
glBindVertexArray(VAO);  
// 用VAO绘制四边形  
glDrawArrays(GL_TRIANGLES, 0, 6);

方法二:VAO+VBO+EBO绘制四边形

// 渲染之前VAO/VBO/EBO的绑定生成
// 顶点数据
float vertices[] = {
0.5f, 0.5f, 0.0f, // 右上
0.5f, -0.5f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f // 左上
};
// 索引数据(注意这里是从0开始的)
unsigned int indices[] = {
0, 1, 3, // 第一个三角形
1, 2, 3 // 第二个三角形
};
// 生成立方体的VAO、VBO和EBO
unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// 绑定VAO
glBindVertexArray(VAO);
// 绑定VBO并传入顶点数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 绑定EBO并传入索引数据
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 解绑VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
// 注意丌要解绑EBO,因为EBO存储在VAO中
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// 解绑VAO
glBindVertexArray(0);
// 渲染时
// 使用之前链接好的着色器程序
glUseProgram(shaderProgram);
// 绑定VAO(实际上丌需要每次绑定)
glBindVertexArray(VAO);
// 用EBO绘制四边形
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

相关内容

热门资讯

【MySQL】锁 锁 文章目录锁全局锁表级锁表锁元数据锁(MDL)意向锁AUTO-INC锁...
【内网安全】 隧道搭建穿透上线... 文章目录内网穿透-Ngrok-入门-上线1、服务端配置:2、客户端连接服务端ÿ...
GCN的几种模型复现笔记 引言 本篇笔记紧接上文,主要是上一篇看写了快2w字,再去接入代码感觉有点...
数据分页展示逻辑 import java.util.Arrays;import java.util.List;impo...
Redis为什么选择单线程?R... 目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、R...
【已解决】ERROR: Cou... 正确指令: pip install pyyaml
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
Lock 接口解读 前置知识点Synchronized synchronized 是 Java 中的关键字,...
Win7 专业版安装中文包、汉... 参考资料:http://www.metsky.com/archives/350.htm...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
大模型未来趋势 大模型是人工智能领域的重要发展趋势之一,未来有着广阔的应用前景和发展空间。以下是大模型未来的趋势和展...
python实战应用讲解-【n... 目录 如何在Python中计算残余的平方和 方法1:使用其Base公式 方法2:使用statsmod...
学习u-boot 需要了解的m... 一、常用函数 1. origin 函数 origin 函数的返回值就是变量来源。使用格式如下...
常用python爬虫库介绍与简... 通用 urllib -网络库(stdlib)。 requests -网络库。 grab – 网络库&...
药品批准文号查询|药融云-中国... 药品批文是国家食品药品监督管理局(NMPA)对药品的审评和批准的证明文件...
【2023-03-22】SRS... 【2023-03-22】SRS推流搭配FFmpeg实现目标检测 说明: 外侧测试使用SRS播放器测...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
初级算法-哈希表 主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-哈希表...
进程间通信【Linux】 1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...
【Docker】P3 Dock... Docker数据卷、宿主机与挂载数据卷的概念及作用挂载宿主机配置数据卷挂载操作示例一个容器挂载多个目...