本篇文章收录于 C++游戏开发的一些高级常识(持续更新)

“你对渲染管线了解多少?”

当我听到这个面试题的时候,我是懵逼的。很长时间以前学的图形学知识,虽然看了红蓝宝书,并且熟悉OpenGL,但是关于渲染管线的细节,仍然有诸多模糊之处,非常惭愧。在19年的时候,我不知死活的去面试业内大厂的的引擎工程师,在这道面试题当中被DISS了。

知耻而后勇,在接下来几个月的学习总结当中,我拿到了公仔厂TIMI的实习OFFER,但是遗憾的是由于实验室老师不放,只能等着秋招再战。通过本文,我将将我理解的渲染管线流程整理如下。本篇文章将分为三个部分进行讲解:

  • GPU渲染流程
  • 图形渲染管线
  • 如何使用纯粹的C++去实现出一个渲染管线,并且支持PBR效果。

全文不涉及任何数学知识,全部是理解的部分,我尽可能用白话来对整个渲染流程进行叙述。如果你想了解透视投影矩阵是怎么推倒的?如何确定View矩阵? 向大家安利《3D游戏与计算机图形学中的数学方法》。这本书里面的很多都是游戏引擎必知的干货。
如果你想打破渲染黑盒,想知道OpenGL背后发生了什么,请关注一下我用1个月疫情时间写的纯C++的PBR渲染管线。具体实现思路在本文第三部分讲解。

纯C++实现PBR软渲染管线Github源码

1.GPU渲染流程

所有渲染,都是将数据从CPU传输到GPU的过程。

从GPU的视角来看渲染的话,非常简洁明了。对于程序整体框架来说大致分为如下的步骤:

  • 应用程序调用图形API(opengl/dx12)。
  • API调用GPU 驱动程序。
  • GPU驱动程序负责将图形API函数转换为GPU可识别编码。
  • CPU将内存当中的Data传递至GPU。
  • 此时GPU拥有数据程序代码,就可以执行,并且将图像渲染至屏幕上。

图1 本图在全局角度去看渲染流程的进行。渲染的本质就是将CPU数据转移到GPU进行计算。

2.图形渲染管线

在上一节从全局角度去看渲染,本节我们深入渲染管线去理解渲染究竟是怎么发生的。如何渲染出炫酷的图像。
图2 再漂亮的图像,也是我们讨论的渲染管线所创建的。来自《上古卷轴5》的郊外。

如图2所示,我们可以看到非常绚丽明亮的色彩,我们分析一下这张图里面的渲染原理。对于道路的石头质感,小屋的木质质感,则是贴图的功劳。对于火焰的光源以及自然的天光,则是光照的功劳。漂亮的模型是建模师通过3dmax努力的结果……当然,为了更加完美的图像,目前3A游戏的制作大多采用PBR光照、各种贴图的叠加、泛光、粒子系统等等的复杂叠加而成的。但是这些高级特点都离不开渲染管线作为基础。我们将渲染所需要的事物抽象如下:

图3 渲染所需要的事物。看起来很简单,天下大事,必作于细。

接下来我们要加速了,开始要进入渲染管线的思维过山车当中,跟紧了。

2.1 渲染管线概览

图4 渲染管线概览。不要害怕,这已经是全部东西了。

接下来我们会针对每一个阶段进行剖析,但是首先,我们来介绍一些基础概念:

  • 应用程序阶段:运行在CPU上的阶段,一般用于输入操作处理、动画处理、事件处理等等。
  • 几何阶段:负责逐个顶点以及逐个图元的操作。
  • 光栅化:以变换化过经过投影的顶点与着色信息为基础,逐个像素进行绘制的操作。将屏幕当中的2D Point转换到屏幕上的像素。
  • 缓冲区:每一个缓冲区都存储着不同的渲染信息,比如Z-Buffer存储的是每个像素的深度信息,模板缓冲区可能存储的是阴影像素。绘制出绚丽的图像,本质上说是诸多缓冲区之间的叠加与计算。
  • shader:着色器,一般在Opengl当中可以编码的是Vertex Shader 与 Fragment Shader。一般在shader当中进行光照方程的数学计算。比如Phong模型、PBR光照模型。

这些概念暂时不懂也没关系,先理解一下, 随着之后深入的探讨,会一一把这些坑填上的。

2.2 应用程序阶段

应用程序阶段是在CPU上运行的,因此开发人员可以完全的控制Application发生的一切。单单理解这个阶段或许难以理解,我们以一款ACT游戏为例:

  • 我们的角色需要绚丽的人物动画,比如:裂天破空斩。
  • 我们的人物斩击到怪物上,被弹刀,产生碰撞
  • 通过键盘鼠标进行输入,d+d+j+k:旋风斩。
  • 逻辑上我们正前方有个怪物,但是由于没有渲染,我们看不到他。我们需要把怪物信息传递给下一个渲染阶段:几何阶段。确定有哪些模型需要渲染。
  • 流水在流动,通过贴图动画产生优美的环境。

综上所述,Application当中的工作就是:处理动画、碰撞、输入、需要渲染的模型。就这么简单。

2.3 几何阶段

几何阶段用来负责逐个顶点的操作。为什么要强调逐个顶点呢。一个模型无论多复杂,都是由顶点组成的。由索引来确定每一个顶点间关系,并且将顶点组合成一个个三角形。在几何阶段,我们集中针对模型当中的顶点进行处理。

2.3.1 Model&View Transform

Model Transform 对于每一个Object,我们都有一个局部坐标系。这个局部坐标系我们称之为Model坐标系。很容易理解,对于我们每个个体来说,当我们说我的胳膊的位置的时候,一般不会说我的胳膊在世界的经纬度,而是说我的胳膊在我身体的左右两侧。而这个坐标系,参照点就是我们自身,这个就是Model坐标系。在进行物体建模的时候,Model坐标系非常适合美术进行操作。比如美工在我后背上插一个金闪闪的翅膀。

但是当我们进行渲染的时候呢,仅仅知道每个物体的局部坐标系可远远不够。比如我现在在天津大学的实验室写下这篇文章,现在要在世界上定位我的位置,我说:我在实验室中间。这是完全不能定位我的位置的。因此,我们需要将局部坐标系转化为世界坐标系。

那么转化成世界坐标系的公式就是:
我的世界坐标 = 天津大学的世界坐标 x 实验室在天津大学的局部坐标 x 我在实验室的局部坐标

好了,例子说完了,我们说一些严肃的。

  • Model Transform:转换的是Model的顶点和法线。
  • 每个Model对应一个Model Transform。
  • 世界坐标系唯一,所有Model经过Model Transform变化后,每一个model都可以使用一个世界坐标对其位置进行唯一描述。

View Transfrom 对于模型世界坐标,这还远远不够。这个世界只有在我们观察的时候,对于我们才是有意义的。(唯心主义的思路)而作为玩家的我们观察虚拟世界的唯一方法就是通过Camera。而我们的目的是:求出其他模型的世界坐标相对于Camera所在的世界坐标的位置。这就引入了View Transform。

  • View Transform : 将模型的世界坐标系转换到Camera的观察坐标系下。是求Model和Camera之间的关系。

2.3.2 Projection

对于透视投影,只要学过图形学的小伙伴一定会知道正交投影和透视投影。但是可能不太清楚,这些看起来憨憨的视景体在渲染当中处于什么样的地位。Projection图形学当中最关键的一步。Projection的目的是:将3D的虚拟空间中的坐标映射到一个2D平面上。这个2D平面,是我们进行光栅化的基础。我们显示器上每一个像素的显示,都是基于这个2D平面生成的。

在渲染管线中,实现Projection很容易,依据当前屏幕的长宽比以及给定的其他参数,我们可以构造一个Projection矩阵,通过将View Space当中的顶点位置乘以Projection矩阵,就可以很容易得到每一个顶点的Clip坐标。对于Clip坐标,其x,y值就是其对应的2D坐标。

(未完待续)

【游戏引擎开发必问】 渲染管线的剖析相关推荐

  1. Python游戏引擎开发(六):动画的小小研究

    今天我们来研究动画,其实这个动画就是一个Sprite+Bitmap的结合体.不造什么是Sprite和Bitmap?=__=#看来你是半路杀进来的,快去看看前几章吧: Python游戏引擎开发(一):序 ...

  2. 游戏引擎开发和物理引擎_视频游戏开发的最佳游戏引擎

    游戏引擎开发和物理引擎 In this article, we'll look at some of the most popular game engines for video game deve ...

  3. 【转载】浅析游戏引擎开发

    浅析游戏引擎开发 1 引言 电脑游戏作为一种娱乐方式越来越为人们所接受.即时通讯开发对于电脑游戏来说, 游戏引擎是用于控制游戏功能的 主程序, 如接受玩家控制信息的输入, 选择合适的声音以合适的音量播 ...

  4. 视频教程-三维游戏引擎开发-图形理论基础-其他

    三维游戏引擎开发-图形理论基础 2004年毕业于西南科技大学,计算机科学技术专业,从事软件开发,游戏开发,擅长游戏开发,桌面应用,手机游戏. 张立铜 ¥117.00 立即订阅 扫码下载「CSDN程序员 ...

  5. python怎么制作游戏图片_Python游戏引擎开发(二):显示图片

    本篇文章是Python游戏引擎开发系列的第二篇文章,主要介绍如何显示图片,大家可以学习下. 在上一章中我们讲了如何创建窗口以及对界面进行重绘.可能有朋友不理解为什么要进行全窗口的重绘呢?我在这里可以大 ...

  6. 游戏引擎与游戏引擎开发入门

    早想写一点游戏设计的文章与大家交流,一是经验的问题,二是公司正在紧张的游戏制作期,实在抽不出多少时间,一直没有动手,今天忽然头脑发热,写了一段,以后准备陆续写一些游戏创意,策划,制作,流程管理,和制作 ...

  7. 用C++实现跨平台游戏引擎开发

    游戏开发系列 用C++实现跨平台游戏引擎开发 你是否梦想写一部格斗游戏但却无从着手呢?是否你只因游戏开发好玩而对之感兴趣?本文我们将分析一个通用的跨平台游戏引擎,每个游戏开发新手都可以自由地使用它. ...

  8. 游戏引擎开发中常用的设计模式

    仅仅因为你知道编程语言的语法,不足以让你成为一个程序员.我讨厌这么对你说,但它确实是真的.什么知识将会使你成为一个真正的程序员呢?答案是数据结构,算法和设计模式的知识.语言的语法与知道字母表同义.任何 ...

  9. 游戏引擎开发入门教程_v20210102

    游戏引擎(Game Engine)是一款游戏的"发动机",是游戏的核心部件,同时也是一个大型软件系统.游戏画面是否绚丽和流畅,游戏场面是否震撼和真实,这些都是由引擎决定的. 从编程 ...

最新文章

  1. 数据蒋堂 | BI系统的前置计算
  2. 【Rain in ACStar HDU-3340】
  3. 30分钟3300%性能提升—python+memcached网页优化小记
  4. 分享珍藏很久的Python学习知识手册
  5. MySQL binlog和redo/undo的概念
  6. keepalived mysql双主架构图_基于keepalived Mysql双主热备配置
  7. [Leetcode]@python 107. Binary Tree Level Order Traversal II
  8. js前端解析excel文件
  9. python类继承实例_python类继承与子类实例初始化用法分析
  10. 系统架构技能之设计模式-抽象工厂模式
  11. Oracle迁移PostgreSQL经验总结
  12. 认识Java虚拟机的基本结构
  13. 数组与字符串的相互转换
  14. visio 2013安装使用
  15. Laravel框架介绍与简介
  16. java分布式事务框架_Java分布式事务,及解决方案
  17. JS使用canvas实现(下雨天)特效
  18. Webots2021b和ROS2调试笔记21-07-27
  19. 程序员用代码写合租广告,网友神评亮了
  20. BugkuCTF之web题之细心

热门文章

  1. 高端化和智能化是一体两面 腾势D9开启中国MPV新豪华时代
  2. 计算机模拟技术 意义,喷丸数值模拟技术的研究意义和发展
  3. 全志F133(D1s)芯片 如何在Tina下进行显示旋转?
  4. 脚手架开发(2)-注册阶段
  5. leetcode进行手机解绑与换绑
  6. mysql三国人物库_一文带你使用neo4j生成三国人物社交关系图
  7. 删库后,除了跑路还能怎么办?
  8. 怎么样才能在CODELITE中输出中文呢!!!
  9. ctfshow misc2 软盘
  10. 影音设备VCD解码板维修一些常识