计算机图形学 | 可编程渲染管线
创始人
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);

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...