如何启用硬件百分比更近的过滤?

时间:2013-06-15 12:41:00

标签: c++ directx hlsl directx-11

我正在尝试对我的shaow贴图实现PCF过滤,因此修改了GPU Gems文章(http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html),以便它可以在当前着色器上运行。修改包括用Texture2D.Sample()函数替换tex2Dproj函数,以便它接受在DirectX11中创建的采样器状态。然后我将偏移值与正常的阴影贴图比较进行比较:

float2 ShTex;
ShTex.x = PSIn.ShadowMapSamplingPos.x/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f;
ShTex.y = -PSIn.ShadowMapSamplingPos.y/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f;
float realDistance = PSIn.ShadowMapSamplingPos.z/PSIn.ShadowMapSamplingPos.w;


(realDistance - xShBias) <= offset_lookup(xTextureSh, texSampler, ShTex, float2(x, y), scale); //Blocker-receiver comparison (the usual stuff, only that it gets 4*4 samples from near offsets then divides the final value with 16)

现在得到的回报是:The staircase effect

文章中所说的内容表明硬件应该神奇地插入结果。我想tex2Dproj可能会这样做,但没有成功让它工作。

最近我遇到了SampleCmpLevelZero函数,我尝试使用此采样器状态:

SamplerComparisonState cmpSampler
{
   Filter = COMPARISON_MIN_MAG_MIP_LINEAR;
   AddressU = Clamp;
   AddressV = Clamp;

   ComparisonFunc = LESS;
};

当我开始工作时,整个场景随机闪烁,从阴影到无阴影和部分阴影(看起来像是正确的阴影)。

xTextureSh.SampleCmpLevelZero( cmpSampler, ShTex.xy, realDistance - xShBias );

可悲的是,我找到了一个有相同问题的人,但他设法通过将过滤器重写为我已应用的模式来修复它。

我的深度纹理采用以下格式:DXGI_FORMAT_R24_UNORM_X8_TYPELESS

我现在对这个关于正确PCF过滤的谜团感到非常困惑,是否有人可以提出任何建议?提前感谢您,并在结束时阅读。

2 个答案:

答案 0 :(得分:4)

好的,我已经完成了。通过使用SampleCmpLevelZero,我试图在HLSL代码中声明SampleComparisonState,但结果却出现了故障。阴影贴图双线性过滤不起作用。 然后我尝试在D3D11 API中创建一个Sampler状态,将D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT设置为描述的过滤器,D3D11_COMPARISON_LESS用于描述的比较功能。 在着色器中我声明了SampleComparisonState而不是通常的SamplerState,并且没有在那里填写描述,但是从api注册了它:

SamplerComparisonState compSampler:register(s2);

然后魔术终于开始了: Bilinear Filtering with manually sampling a 4*4 grid of texels

正如您所看到的,结果是阴影周围的无缝半影而不是楼梯。即使没有上一张图片的手动采样,我们也可以通过一个手动样本(以及SampleCmpLevelZero完成的更多自动样本)获得完全可接受的结果:One manual sample

可悲的是,我不知道导致着色器内部采样器声明出现故障的原因,我不喜欢这样。如果有人经历过这样的事情,如果他/她与我合影,我会很高兴。

还要感谢MHGameWork试图帮助我解决这个问题。

更新:由于问题问题已经过了很长时间,因此我在此期间知道在着色器中声明采样器的问题,所以我把它放在这里:你只能在一个内部声明采样器对象如果您正在使用效果框架,请使用着色器。使用准系统着色器时,需要通过API调用上传。

答案 1 :(得分:2)

来自http://msdn.microsoft.com/en-us/library/windows/desktop/bb205073(v=vs.85).aspx#Mapping_Texels_to_Pixels_DX10

在D3D10中改变纹理坐标,您是否考虑过这个?它们现在处于半单位,就像像素一样(以及D3D9中的位置)。

如果您在移植时没有考虑到这一点,那么您现在正在以确切的纹理元素位置进行采样,我认为这不会导致您以着色器的方式进行双线性插值。

编辑:因为你正确地做了这个:)我可能有另一个解决方案:

如果GenerateMips无法生成,则会无声地失败。
我认为无法为DXGI_FORMAT_R24_UNORM_X8_TYPELESS生成mipmap。您可以在此处查看支持的格式列表:http://msdn.microsoft.com/en-us/library/windows/desktop/bb173569(v=vs.85).aspx