DirectX(九)

来源:互联网 发布:精选淘宝怎么卸载 编辑:程序博客网 时间:2024/04/30 09:52

高斯模糊

其实模糊滤波器就是对周围像素进行加权平均处理,均值模糊很简单,周围像素的权值都相同,所以不是很平滑。高斯模糊就有这个优点,所以被广泛用在图像降噪上。特别是在边缘检测之前,都会用来移除细节。那么下面我们就看看高斯模糊的权值是如何分配的。
这里写图片描述
正态分布显然是一种可取的权重分配模式。在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。计算平均值的时候,我们只需要将”中心点”作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。
上面对高斯模糊的介绍转自http://www.cnblogs.com/magic8sky/p/6104377.html

Compute Shader实现高斯模糊

模糊Shader

//模糊滤镜cbuffer cbSettings{    float gWeights[11] =     {        0.05f, 0.05f, 0.1f, 0.1f, 0.1f, 0.2f, 0.1f, 0.1f, 0.1f, 0.05f, 0.05f,    };};//模糊半径cbuffer cbFixed{    static const int gBlurRadius = 5;};//输入Texture2D gInput;//输出RWTexture2D<float4> gOutput;#define N 256//缓存大小#define CacheSize (N + 2*gBlurRadius)groupshared float4 gCache[CacheSize];//水平模糊[numthreads(N, 1, 1)]void HorzBlurCS(int3 groupThreadID : SV_GroupThreadID,                int3 dispatchThreadID : SV_DispatchThreadID){    if(groupThreadID.x < gBlurRadius)    {        int x = max(dispatchThreadID.x - gBlurRadius, 0);        gCache[groupThreadID.x] = gInput[int2(x, dispatchThreadID.y)];    }    if(groupThreadID.x >= N-gBlurRadius)    {        int x = min(dispatchThreadID.x + gBlurRadius, gInput.Length.x-1);        gCache[groupThreadID.x+2*gBlurRadius] = gInput[int2(x, dispatchThreadID.y)];    }    gCache[groupThreadID.x+gBlurRadius] = gInput[min(dispatchThreadID.xy, gInput.Length.xy-1)];    //等待    GroupMemoryBarrierWithGroupSync();    //模糊    float4 blurColor = float4(0, 0, 0, 0);    [unroll]    for(int i = -gBlurRadius; i <= gBlurRadius; ++i)    {        int k = groupThreadID.x + gBlurRadius + i;        blurColor += gWeights[i+gBlurRadius]*gCache[k];    }    gOutput[dispatchThreadID.xy] = blurColor;}//垂直模糊[numthreads(1, N, 1)]void VertBlurCS(int3 groupThreadID : SV_GroupThreadID,                int3 dispatchThreadID : SV_DispatchThreadID){    if(groupThreadID.y < gBlurRadius)    {        int y = max(dispatchThreadID.y - gBlurRadius, 0);        gCache[groupThreadID.y] = gInput[int2(dispatchThreadID.x, y)];    }    if(groupThreadID.y >= N-gBlurRadius)    {        int y = min(dispatchThreadID.y + gBlurRadius, gInput.Length.y-1);        gCache[groupThreadID.y+2*gBlurRadius] = gInput[int2(dispatchThreadID.x, y)];    }    gCache[groupThreadID.y+gBlurRadius] = gInput[min(dispatchThreadID.xy, gInput.Length.xy-1)];    GroupMemoryBarrierWithGroupSync();    float4 blurColor = float4(0, 0, 0, 0);    [unroll]    for(int i = -gBlurRadius; i <= gBlurRadius; ++i)    {        int k = groupThreadID.y + gBlurRadius + i;        blurColor += gWeights[i+gBlurRadius]*gCache[k];    }    gOutput[dispatchThreadID.xy] = blurColor;}technique11 HorzBlur{    pass P0    {        SetVertexShader( NULL );        SetPixelShader( NULL );        SetComputeShader( CompileShader( cs_5_0, HorzBlurCS() ) );    }}technique11 VertBlur{    pass P0    {        SetVertexShader( NULL );        SetPixelShader( NULL );        SetComputeShader( CompileShader( cs_5_0, VertBlurCS() ) );    }}
//对输入纹理1进行一次水平模糊输出到纹理2上,在设置输入纹理为纹理2,输出纹理为纹理1,进行垂直模糊。void BlurFilter::BlurInPlace(ID3D11ShaderResourceView* inputSRV, ID3D11UnorderedAccessView* inputUAV, int blurCount){    ID3D11DeviceContext* dc = D3d->GetContext();    UINT width = D3d->GetWidth();    UINT height = D3d->GetHeight();    ID3D11ShaderResourceView* nullSRV[1] = { 0 };    ID3D11UnorderedAccessView* nullUAV[1] = { 0 };    for (int i = 0; i < blurCount; ++i)    {        //水平模糊        D3DX11_TECHNIQUE_DESC techDesc;        Effects::BlurFX->HorzBlurTech->GetDesc(&techDesc);        for (UINT p = 0; p < techDesc.Passes; ++p)        {            Effects::BlurFX->SetInputMap(inputSRV);            Effects::BlurFX->SetOutputMap(m_BlurredOutputTexUAV);            Effects::BlurFX->HorzBlurTech->GetPassByIndex(p)->Apply(0, dc);            UINT numGroupsX = static_cast<UINT>(ceilf(width / 256.0f));            dc->Dispatch(numGroupsX, height, 1);        }        dc->CSSetShaderResources(0, 1, nullSRV);        dc->CSSetUnorderedAccessViews(0, 1, nullUAV, 0);        //垂直模糊        Effects::BlurFX->VertBlurTech->GetDesc(&techDesc);        for (UINT p = 0; p < techDesc.Passes; ++p)        {            Effects::BlurFX->SetInputMap(m_BlurredOutputTexSRV);            Effects::BlurFX->SetOutputMap(inputUAV);            Effects::BlurFX->VertBlurTech->GetPassByIndex(p)->Apply(0, dc);            UINT numGroupsY = static_cast<UINT>(ceilf(height / 256.0f));            dc->Dispatch(width, numGroupsY, 1);        }        dc->CSSetShaderResources(0, 1, nullSRV);        dc->CSSetUnorderedAccessViews(0, 1, nullUAV, 0);    }    //关闭Compute Shader    dc->CSSetShader(0, 0, 0);}

在Render To Texture 中加入高斯模糊。
这里写图片描述
项目Github地址https://github.com/xinhua302/Graphics-Engine

原创粉丝点击