更加快速的CPU视锥剔除
GPU除外,CPU的frustum culling还有什么优化的空间
https://www.zhihu.com/question/313499217/answer/2862700086
- 缓存友好
所有bounding相关信息存到一个数组里1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* Bounding information used to cull primitives in the scene.
*/
struct FPrimitiveBounds
{
FBoxSphereBounds BoxSphereBounds;
/** Square of the minimum draw distance for the primitive. */
float MinDrawDistanceSq;
/** Maximum draw distance for the primitive. */
float MaxDrawDistance;
/** Maximum cull distance for the primitive. This is only different from the MaxDrawDistance for HLOD.*/
float MaxCullDistance;
};
/** Packed array of primitive bounds. */
TArray<FPrimitiveBounds> PrimitiveBounds; - 多线程
- SIMDGDC16: Improving geometry culling for Deus Ex: Mankind Divided by Nicolas Trudel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// Process four planes at a time until we have < 4 left
for (int Count = 0; Count < Planes.Num(); Count += 4)
{
// Load 4 planes that are already all Xs, Ys, ...
Register128 PlanesX = SIMD_Load(PlanePtr);
FrustumPlanesPlanesPtr++;
Register128 PlanesY = SIMD_Load(FrustumPlanesPlanesPtr);
FrustumPlanesPlanesPtr++;
Register128 PlanesZ = SIMD_Load(FrustumPlanesPlanesPtr);
FrustumPlanesPlanesPtr++;
Register128 PlanesW = SIMD_Load(FrustumPlanesPlanesPtr);
FrustumPlanesPlanesPtr++;
// Calculate the distance (x * x) + (y * y) + (z * z) - w
Register128 DistX = SIMD_Mul(OrigX,PlanesX);
Register128 DistY = SIMD_Mad(OrigY,PlanesY,DistX);
Register128 DistZ = SIMD_Mad(OrigZ,PlanesZ,DistY);
Register128 Distance = SIMD_Sub(DistZ,PlanesW);
// Check for completely outside
if (SIMD_GreaterThan(Distance,VRadius))
{å
return false;
}
}
Nanite Occlusion Culling
https://zhuanlan.zhihu.com/p/583245401
- Software Occulsion Culling
https://www.intel.com/content/www/us/en/developer/articles/technical/software-occlusion-culling.html
我们现在用的是occluder调用 Intel的Software Occulsion Culling- 用CPU对occluder做软光栅化生成depth buffer
- 对所有物体做depth test culling
- gpu driven管线则可以把frustum culling, occlusion culling, cluster draw 全都放到GPU上
- 大革命
- 提出假设,两帧画面的zbuffer具有足够的连续性,因此我们可以把上一帧的zbuffer投影到当前帧进行遮挡剔除
- 遮挡问题
- 动态物体 延迟
- two pass
- 提出假设,两帧画面的zbuffer具有足够的连续性,因此我们可以把上一帧的zbuffer投影到当前帧进行遮挡剔除
- Nanite
- two pass 1
- two pass 2
- 这一帧可见的cluster大概率在上一帧也可见
- 把当前帧所有cluster都转换到上一帧的位置上去,然后利用上一帧的hi-z进行遮挡剔除
- 再对被剔除的cluster进行第二次保守剔除
- two pass 1