Shader|DrawCall

  1. Draw Call中造成性能问题的元凶是CPU,是由于CPU的准备工作时间较长。
  2. 如果没有流水线化,那么CPU需要等到GPU完成上一个渲染任务才能再次发送渲染命令,这样会造成效率低下。我们可以使用一个命令缓冲区让CPU和GPU并行工作。

命令缓冲区

    命令缓冲区中包含了一个命令队列,由CPU向其中添加命令,而由GPU从中读取命令,添加和读取的过程是相互独立的。命令缓冲区使得CPU和GPU可以相互独立工作。当CPU需要渲染一些对象时,它可以向命令缓冲区中添加命令,而当GPU完成了上一次的渲染任务后,它就可以从命令队列中再取出一个命令并执行它。
    命令缓冲区中的命令有很多种类,如:DrawCall(下图黄色区域)、改变渲染状态(下图红色区域,比较耗时)等。

    Shader|DrawCall_第1张图片

    在每次调用DrawCall之前,CPU需要向GPU发送很多内容,包括数据、状态和命令等。在这一阶段,CPU需要完成很多工作,例如检查渲染状态等。而一旦CPU完成了这些准备工作,GPU就可以开始本次的渲染,GPU的渲染能力很强,因此渲染速度往往取决于CPU提交命令的速度。如果DrawCall的数量太多,CPU就会把大量时间花费在提交DrawCall上,造成CPU的过载。
    如下图,虚线方框表示GPU已经完成了的命令。此时,命令缓冲区中没有执行命令了,GPU处于空闲状态,而CPU还没有准备好下一个渲染命令。


    Shader|DrawCall_第2张图片

减少DrawCall
 
    批处理:把很多小的DrawCall合并成一个大的DrawCall。合并的过程是耗时的,所以批处理技术更适合于那些静态的物体,对于静态的物体只需要合并一次,如大地、障碍物等。但是,使用批处理合并的网络将会使用同一种渲染状态,也就是说,如果网格之间需要使用不同的渲染状态,那么就无法使用批处理技术。

    在游戏开发中,为了减少DrawCall的开销,需要注意:
  1. 避免使用大量较小的网格。当不可避免地使用很小的网格结构时,考虑是否可以合并它们。
  2. 避免使用过多的材质。尽量在不同的网格之间共用同一个材质。




你可能感兴趣的:(Shader|DrawCall)