相机设置区分:
RenderManager::RenderCameras下会根据是否是立体渲染区分来执行不同的渲染,也就是RenderStereo和Render(立体渲染在内部进行消隐),剔除会分standalone和Stereo,也就是部分眼球的渲染方式和分左右眼球的渲染方式(vr)。所以他在RenderCameras中如果是立体渲染则cull在RenderStereo里面执行,因为要分左右眼剔除。如果不是则在RenderCameras中就直接先剔除了。
相机剔除:
剔除函数在Camera下的Cull里。cull会执行CustomCull
1.计算边界:
首先会执行OnPreCull的发送“SendMessage (kPreCull);”然后如果有地形terrain(CullAllTerrains),会先剔除地形,根据layer,重新计算地形贴图信息。然后更新场景的边界,并准备好摄像机边界数据和渲染类型。然后通过RecalculateDirtyBounds来更改场景的边界。
2.准备场景剔除数据:
PrepareSceneCullingParameters里面会组织边界范围,节点,渲染数量等信息到sceneCullParameters的renderers中,然后到CalculateCullingParameters中根据这些信息计算平截头体的信息。
3.lod设置:
然后根据设置的lod计算lod的切换距离,他是根据当前距离除以fadeDistance来确定切换的距离的。(CalculateLODMasks)
4.替换shader设置:
然后他会看是否有替换的shader,如果有替换的shader会用替换的shader给到“results.shaderReplaceData”
5.物体投放阴影剔除:
然后OnPreCull阶段还会准备剔除的灯光数据,其实就是设置灯光的数据,比如矩阵数据,哪个摄像机,宽高,可视范围等。“SetupShadowCullData(*parameters.cullingCamera, parameters.cullingCamera->GetPosition(), results.shaderReplaceData, &results.sceneCullParameters, shadowCullData);”然后放到results.shadowCullData。
他的阴影剔除计算是获取阴影的最大距离,首先要确定是否能用正交投影方式剔除,他判断是否能用的方式是计算摄像机需要投影的距离是否大于平截头体的区域,如果大于则不能用,如果小于则可以用。
然后如果不能用正交投影的方式剔除的话,会先建立一个隐藏的摄像机矩阵,最后放入到cullData.cameraWorldToClip中。然后把平截头体的远平面座位他的剔除面板距离给到baseFarDistance。在CalculateSphericalShadowRange计算阴影范围。这些数据都设置到cullData中。
6.正式物体剔除:
接下来就开始剔除了。GetRenderImmediateObjects()是说是否当指剔除中间的渲染对象,在发布的包中是false。我们只看正式的,CullScene。
遮挡剔除:
如果有用遮挡剔除useOcclusionCulling,如果有用的话就执行CullSceneWithUmbra,然后里面用CullDynamicObjectsUmbra对可见对象一个一个测试他的aabb的可视性。
ProcessIndexListIsNodeVisible,里面是判断是否可见,就假如可见索引列表。
CullSceneWithoutUmbra是不用遮挡剔除的处理,对每个物体判断IntersectAABBPlaneBounds,
通过举例判断是否要剔除。也就是他只判断aabb,如果aabb不通过则不渲染,最终也通过
ProcessIndexListIsNodeVisible里面判断是否可见,就假如可见索引列表。
7.灯光剔除准备:
然后PrepareSceneNodes准备场景节点数据,CullLights开始剔除光源。
剔除光源会先找到符合的光源FindAndCullActiveLights,符合的光源是他是enabled的,确定他的光照范围。FrustumCullLocalLights确定他的横截面上的信息,如果在平截头体内则可以渲染,如果开启了遮挡剔除,还会进入OcclusionCullLocalLights,根据光照的aabb决定是否剔除。AddDirectionalLights设置主光源,这个主要针对直线光。然后就是AddActiveLocalLights跟其他点光源,聚光灯等做剔除,CalculateLightScreenBounds判断各种光照是否在场景范围内。
8.灯光正式剔除:
然后CacheTransformInfo就会把这些可见物缓存住。然后进入CullAllPerObjectLights对对象一个一个剔除。会进入到CullPerObjectLights这里会根据你是直线光,点光,聚光执行一个一个的判断剔除。
灯光阴影:
然后如果有光照的阴影还会判断光照给的阴影是否需要剔除FindShadowCastingLights,也是判断是否可见是否在场景内来剔除。
剔除完灯光就开始发事件改变场景状态CullSendEvents。
结束相机渲染:
最后RenderCameras渲染完需要重置数据scene.EndCameraRender();也就是说每一帧都需要初始化数据以及重置数据。