[计算机图形学06]OpenGL和DirectX

什么是OpenGL/DirectX

只要接触过图像编程就一定听说过OpenGLDirectX,也知道这两者之间存在着竞争关系。这两者实际上就是图像应用编程接口,这些接口用于渲染二维或三维图形。可以说,这些接口充当了上层应用程序底层GPU的沟通桥梁。一个应用向这些接口发送渲染命令,而这些接口会依次向显卡驱动发送渲染命令,这些显卡驱动是真正知道如何与GPU通信的,正是它们把OpenGL/DirectX的函数调用翻译成了GPU能够识别的指令。另外,一块显卡除了有图像处理单元GPU之外,还拥有自己的内存,这个内存通常被称为显存。GPU可以在显存中存储任何数据,但是对于渲染而言有一些数据类型是必须的,所以一般显存中都包含图像缓存深度缓存纹理缓存顶点缓存
因为显卡驱动的存在,几乎所有的GPU都可以和OpenGL/DirectX一起合作。从显卡的角度出发,实际上,它只需要和显卡驱动打交道就可以了。而显卡驱动就好像一个中介,负责和两方沟通。因此,一个显卡制造商为了让他们的显卡可以同时和OpenGL和DirectX合作,就必须提供支持这两个接口的显卡驱动。

什么是HLSL,GLSL,CG

在可编程渲染管线出现之前,为了编写着色器代码,开发者们需要学习汇编语言。为了给开发者们方便,就出现了更高级的着色器语言(Shading Language),常见的着色器语言有DiretX的HLSL(High Level Shading Language),OpenGL的GLSL(OpenGL Shading Language)以及NVIDIA的CG(C for Graphic)。HLSL,GLSL,CG都是“高级”语言,但是这个高级实际上是相对汇编语言来说的。这些语言会被编译成为与机器无关的汇编语言,也被成为中间语言(Intermediate Language)。然后这些中间语言才会被显卡驱动来翻译成为真正的机器语言,即GPU可以理解的语言

什么是 Draw Call

Draw Call本身的含义很简单,就是调用图像编程接口,如OpenGL中glDrawElements命令或者DirectX中的DrawIndexedPrimitive命令,来命令GPU进行渲染的操作。一个很常见的误区是,Draw Call中造成性能问题的元凶是GPU,认为GPU上的状态切换是耗时的,其实不是的,真正“拖后腿”其实是CPU。

CPU和GPU是怎样实现并行工作的?

如果没有流水线化,那么CPU需要等到GPU完成上一个渲染任务才能再次发送渲染指令,这种方法显然会造成效率地下。解决的办法也很简单,就是使用一个命令缓冲区(Command Buffer)。命令缓冲区包含了一个队列,由CPU添加命令,而由GPU从中读取命令,值得注意的是,添加和读取的过程是相互独立的。命令缓冲区的存在是的CPU和GPU可以相互独立。当CPU需要渲染一些对象时,它可以向缓冲区中添加命令,而当GPU完成了上一次渲染任务后,它从命令队列中再取出一个命令并且执行它。
命令缓冲区中的命令有很多种类,而Draw Call只是其中一种,其它命令还有改变渲染状态等等。

为什么Draw Call多了会影响帧率?

我们先来做一个实验:请创建10000个小文件,每个文件的大小为1KB,然后把它们从一个文件夹复制到另一个文件夹中。你会发现,尽管这些文件的空间总和不超过10MB,但还是要花费很长的时间。然后你再创建一个10MB的文件,把这个文件从一个文件夹复制到另一个文件夹中,这次复制操作所消耗的时间却少很多!会发生这样的现象的原因在于,每一个复制动作需要有很多额外的操作,比如分配内存创建各种各样的元数据,这些操作将造成很多额外的性能开销。
渲染的过程虽然和复制一大堆文件不一样,但是从感性的认知来说这两点是有相同点的。在每一次调用Draw Call前,CPU要向GPU发送很多内容,包括数据,状态和命令等。GPU的渲染能力是很强的,渲染200个还是2000个三角形网络通常没有什么区别,因此渲染速度往往会快于CPU提交命令的速度。如果Draw Call的数量太多,CPU就会把时间大量浪费在提交Draw Call上,造成CPU的过载。

如何减少Draw Call?

一个显然的优化想法就是把很多小的Draw Call合并成为一个大的Draw Call这就是批处理的思想。值得注意的是,由于我们需要在CPU的内存中合并网格,而合并的过程是需要消耗时间的。因此,批处理技术更加适合那些处于静态的物体,例如不会移动的大地,石头等。

Shader究竟是什么?

  1. GPU流水线上一些可高度编程的阶段,而由着色器编译出来的最终代码是会在GPU上运行的。
  2. 有一些特定类型的着色器,如顶点着色器,片元着色器等。
  3. 依靠着色器我们可以控制流水线中的渲染细节,例如顶点着色器来进行顶点变换以及传递数据,用片元着色器来进行逐像素的渲染

你可能感兴趣的:(图形学)