天天看点

Unity - DrawCall, Batch, SetPassCall区别啥叫:DrawCall啥叫:SetPassCall啥叫:BatchReferences

一般我们 在实时渲染中,DC也就是 DrawCall 都会尽可能的降低,因为这会比较直接的降低 CPU 与 GPU 的绘制沟通

啥叫:DrawCall

以 OpenGL 为例,就是调用带有绘制功能的 API 的次数

如:DrawCall : 10 次,那就意味着调用了 glDrawXXXX 的 API 10 次

啥叫:SetPassCall

Unity 中,就无缘无故多了个叫:SetPassCall 的家伙

其实早在以前的游戏引擎里,没有 pass 这么一个说法,或是 techni 的说法

因为这些都是封装的功能

可以查看我之前学习 OpenGL 时,写的一篇,添加 类似 Unity Pass 功能的文章:

LearnGL - 17 - Geometry Shader - 几何着色器 - 直接网页锚点定位到对应的 Pass 实现

一般 OpenGL 中,绘制一个对象,就是提供,VBO,IBO(IBO还不一定需要提供,可以使用 DrawArray 直接通过VBO来绘制,如果通过DrawArrayIndex 之类的就需要 IBO 了,前面的 VBO,IBO 也可以通过 VAO 统一绑定后设置),然后指定 shader(VS,FS,其他的按需提供),就可以调用 DC(DrawCall) API 来绘制就可以了

而 Unity 的 ShaderLab 中可以看到有 Pass 块的代码

其实每个 Pass 块的代码都是一个可以用于完整的 SetDrawState, DrawCall 的过程

因为 ShaderLab 中指定了一部分 DrawCall 前的绘制状态的设置配置,如:ZTest,ZWrite,Cull,Blend,ColorMask,Stencil 等,而 Pass 中的 #param vert XXX, #param frag XXX 就是我们的 VS,FS

所以 Unity 多了个:SetPassCall

SetPassCall = SetStateBeforeDraw & Draw 的两者结合

啥叫:Batch

Batch 直译:批量,的意思

在 实时渲染 中,已动态合批为例(Dynamic Batch)一般理解为:为了减少 DrawCall,或是减少 SetPassCall 而将绘制时材质一样(或是说 shader + shader 参数 + 绘制前状态,都一样)的 VBO,IBO,等数据打包到一个大的 VBO,或是 IBO 中,然后在调用一次 DrawCall,从而提升性能:SetPass 的 State 时,或是多次 Draw API 调用产生过多的 CPU 消耗的性能的问题

(另外还有:静态合批(Static Batch)、Instanced 批量(GPU Instancing Batch)绘制,都算是 Batch 的方式)

所以 Batch 的目的是:将原本需要 多次 SetDrawState + 多次 DrawCall,优化为:1次 SetDrawState + 1次 DrawCall

References

  • Batch, Draw Call, Setpass Call - 讲的还不错,但还不够完美
  • Draw Calls vs Batches optimization? [Unity 5] - 该帖子中的 colin299 用户回答得唯一不对的就是 Batch 的理解

继续阅读