遮挡剔除处理奇怪的结果

问题描述 投票:0回答:0

我有一些奇怪的遮挡剔除结果。对象正在剔除,但不是正确的方式。为了根据深度剔除对象,我使用对象的轴对齐边界框,它是我在对象加载时生成的,所以它在模型空间中。然后我将它转换为着色器中的剪辑空间,如下所示:

float3 BoxMin = MeshOffsets[MeshIndex].AABB.Min.xyz * MeshDrawCommandData[DrawIndex].Scale + MeshDrawCommandData[DrawIndex].Translate.xyz;
float3 BoxMax = MeshOffsets[MeshIndex].AABB.Max.xyz * MeshDrawCommandData[DrawIndex].Scale + MeshDrawCommandData[DrawIndex].Translate.xyz;
float4 ProjMinTemp = mul(Proj, float4(BoxMin, 1));
float4 ProjMaxTemp = mul(Proj, float4(BoxMax, 1));
float3 ProjBoxMin = ProjMinTemp.xyz / ProjMinTemp.w;
float3 ProjBoxMax = ProjMaxTemp.xyz / ProjMaxTemp.w;

我使用 Hierarchy-Z z-buffer 进行剔除。问题是,一般来说,书籍和论文都说我应该使用从纹理收集的纹素中的最小值或最大值。但对我来说,不知何故,它并没有真正奏效。当我在深度纹理减少上使用最小/最大时,产生的遮挡剔除真的很奇怪。例如:

这是没有遮挡剔除的原图:

当我尝试在减少时对 z-buffer 进行平均时,结果更好:

但是平均方法的问题是有些远处的物体在闪烁,有些则没有(中近处的物体很好)。尽管如此,据我所知,最好的结果就在这里。

以防万一,剔除路由本身:

bool IsNotOccluded = true;
float3 BoxDims = (ProjBoxMax - ProjBoxMin);
if(IsVisible && MeshCullingCommonInput[0].OcclusionCullingEnabled)
{
    uint Lod = ceil(log2(max(BoxDims.x * MeshCullingCommonInput[0].HiZWidth, BoxDims.y * MeshCullingCommonInput[0].HiZHeight)));

    float4 Texel = HiZDepthTextures[Lod].Gather(DepthSampler, BoxDims.xy * 0.5);

    float ObjDepth = ProjBoxMax.z;
    IsNotOccluded = (ObjDepth > (max(max(Texel.x, Texel.y), max(Texel.z, Texel.w)) - 0.01)); // Some bias to get rid of back flickering
}

基本上,我如何才能正确使用生成的具有最小/最大功能的 Hi-Z 缓冲区?使用通过平均生成的 Hi-Z 缓冲区可以吗?

graphics 3d hlsl occlusion
© www.soinside.com 2019 - 2024. All rights reserved.