要进入静态批处理,需要给到channel,unity的channel保存的是包括顶点信息,uv信息之类的材质相关信息。
PrePassRenderLoop::RenderBasePass或者 ForwardShaderRenderLoop::PerformRendering或者ForwardShaderRenderLoop::CollectShadows或者
PrePassRenderLoop::RenderFinalPass执行m_BatchRenderer.Add,把组织好的channel放到批处理里,channel的获取是通过Unity::Material的SetPassWithShader来返回的,最终是通过shade的setpass来指定pass的id和子id来获取到。
ChannelAssigns中,其中m_Channels里面是对所有顶点数据的指定。
然后m_BatchRenderer.Add加进去的是m_BatchInstances列表。包括把renderer,subsetIndex等放进入。
在BatchRenderer::Flush()的时候,如果是批处理,比如mesh就会走MeshRenderer::RenderMultiple (m_BatchInstances.begin(), instanceCount, *m_ActiveChannels);
他获取MeshRenderer中的GetMeshStaticBatchIndex,如果id不为0则是静态批处理。
他判断是在Renderer.h中判断IsPartOfStaticBatch,里面是通过HasSubsetIndices,也就是看m_SubsetIndices是否有值,有的话就是静态批处理。
c++中判断如果是静态批处理则执行到RenderStaticBatch。
编辑器收集静态对象:
这个标记是编辑器时标记的,他会通过MeshRenderer::SetSubsetIndex来设置然后执行到Renderer::SetSubsetIndex,会把所有材质以及自身设置为其中一个index。
c#到c++的收集过程:
而真正让他执行这一步是在c#中的。在c#的CombineForStaticBatching.cs中执行Combine的时候会拿到transform中是否有静态标记,有静态标记的则收集到一起
最终执行MakeBatch,让手机的subsets都执行renderer的SetSubsetIndex,就开始记录到c++的MeshRenderer::SetSubsetIndex了。
静态批处理处理步骤:
静态批处理有三个处理步骤,分别是BeginStaticBatching,StaticBatchMesh,EndStaticBatching。
BeginStaticBatching
BeginStaticBatching是构建StaticBatch,并把数据结构填好初始值。包括channel也是在这里确定的。同一个批次的channel必须是一致的。
StaticBatchMesh
StaticBatchMesh就是把顶点数,顶点起始终点,顶点索引不断的添加进来。
EndStaticBatching
EndStaticBatching就是要开始对添加进来的所有顶点整合完后开始渲染。他执行vbo的DrawCustomIndexed。然后如果是opengles3的话会组织成DataBufferGLES30,里面是基于3的buffer数据。用RecreateWithData来重组当前批次的数据。然后执行Draw。
Draw
draw这里就是真正执行opengl接口的地方。他有两个模式,一个是vao的,如果是vao则直接切换vao就好。如果不是vao模式则要重新设置顶点数据。就要拿出ChannelAssigns来一个一个设置进去,在ComputeVertexInputState中。
通过SetupDefaultVertexArrayStateGLES30来真正执行opengl顶点数据的设置。
在draw的后面就是开始渲染了
静态批处理的渲染顺序处理
在静态批处理中他对半透明或者不透明的渲染都是排序正确的。这个正确的处理的方式是,unity只记录了哪些合在一起,但是editor下并不是把他们都合在一个mesh上了。而是作为一个submesh记录下来。
然后在运行时的时候还是对物体做正确的排序,然后排序后的静态物体instance填入一个vbo中,所以就只有一个批次了,unity还需要你保证材质是一样的,不然也只能是多个dc。
处理过程:
如果是前向渲染,ForwardShaderRenderLoop::PerformRendering这里会通过
加入批处理中,注意这里的renderer已经排过序的,所以他的顺序是对的。
在RenderStaticBatch中的StaticBatchMesh会根据instances的顺序加入vbo中,所以这里时正确的。