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
阅读全文
0 0
- DirectX(九)
- 3D游戏编程入门(九)DirectX简介
- DirectX
- DirectX
- DirectX
- DirectX
- directx
- DirectX
- directX
- DirectX
- DirectX
- Directx
- Directx
- directX
- DirectX
- DirectX
- DirectX
- DirectX
- 概率DP [Lydsy2017年4月月赛]抵制克苏恩
- POJ
- remove duplicates from sorted array
- 作弊式刷题 7 30
- 接口和抽象类
- DirectX(九)
- 进程管理--之二
- C/S和B/S网络架构的区别
- 解决 Visual Studio 卸载不完全的问题
- Java容器简介-欢迎大佬指正
- 框架学习之struts2-04数据类型转化和数据校验
- Linux学习小结(二)
- Socket.io在Swift中的应用
- 集合