在UnrealEngine中用Custom节点实现高斯模糊
3x3高斯模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input UV 屏幕缓存的坐标 //14是原始颜色 int tIndex=14; float4 x1y1=0.0625*SceneTextureLookup(UV+float2(-1.0f/sW,-1.0/sH),tIndex,false); float4 x2y1=0.125*SceneTextureLookup(UV+float2(0.0f,-1.0/sH),tIndex,false); float4 x3y1=0.0625*SceneTextureLookup(UV+float2(1.0f/sW,-1.0/sH),tIndex,false); float4 x1y2=0.125*SceneTextureLookup(UV+float2(-1.0f/sW,0.0f),tIndex,false); float4 x2y2=0.25*SceneTextureLookup(UV+float2(0.0f,0.0f),tIndex,false); float4 x3y2=0.125*SceneTextureLookup(UV+float2(1.0f/sW,0.0f),tIndex,false); float4 x1y3=0.0625*SceneTextureLookup(UV+float2(-1.0f/sW,1.0/sH),tIndex,false); float4 x2y3=0.125*SceneTextureLookup(UV+float2(0.0f,1.0/sH),tIndex,false); float4 x3y3=0.0625*SceneTextureLookup(UV+float2(1.0f/sW,1.0/sH),tIndex,false); return x1y1+x2y1+x3y1+x1y2+x2y2+x3y2+x1y3+x2y3+x3y3;
3X3均值模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input UV 屏幕缓存的坐标 //14是原始颜色 int tIndex=14; float4 x1y1=SceneTextureLookup(UV+float2(-1.0f/sW,-1.0/sH),tIndex,false); float4 x2y1=SceneTextureLookup(UV+float2(0.0f,-1.0/sH),tIndex,false); float4 x3y1=SceneTextureLookup(UV+float2(1.0f/sW,-1.0/sH),tIndex,false); float4 x1y2=SceneTextureLookup(UV+float2(-1.0f/sW,0.0f),tIndex,false); float4 x2y2=SceneTextureLookup(UV+float2(0.0f,0.0f),tIndex,false); float4 x3y2=SceneTextureLookup(UV+float2(1.0f/sW,0.0f),tIndex,false); float4 x1y3=SceneTextureLookup(UV+float2(-1.0f/sW,1.0/sH),tIndex,false); float4 x2y3=SceneTextureLookup(UV+float2(0.0f,1.0/sH),tIndex,false); float4 x3y3=SceneTextureLookup(UV+float2(1.0f/sW,1.0/sH),tIndex,false); return (x1y1+x2y1+x3y1+x1y2+x2y2+x3y2+x1y3+x2y3+x3y3)/9;
看了官方论坛的帖子,法线Custom里面可以写for循环,于是……
//5x5高斯模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input UV 屏幕缓存的坐标 //14是原始颜色 int tIndex=14; int UVOfferset[]={-2,-1,0,1,2}; float Weights[]= { 0.0036,0.0146,0.0256,0.0146,0.0036, 0.0146,0.0586,0.0952,0.0586,0.0146, 0.0256,0.0952,0.1501,0.0952,0.0256, 0.0146,0.0586,0.0952,0.0586,0.0146, 0.0036,0.0146,0.0256,0.0146,0.0036 }; float3 OutColor={0.0,0.0,0.0}; for(int i=0;i<=4;i++) { for(int j=0;j<=4;j++) { OutColor+=Weights[i*5+j]*SceneTextureLookup(UV+float2(UVOfferset[j]/sW,UVOfferset[i]/sH),tIndex,false).xyz; } } return float4(OutColor,1.0f);
参考了一下网上的文章写了个可以动态调整的高斯模糊
//动态高斯模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input Radius 模糊半径 //input UV 屏幕缓存的坐标 //14是原始颜色 int tIndex=14; if(Radius<1.0) return SceneTextureLookup(UV,tIndex,false); float3 OutColor={0.0,0.0,0.0}; Radius=floor(Radius); float Sigma=Radius/3; float Sigma2=2*Sigma*Sigma; int Number=Radius; float WeightsSum; for(int i=-Number;i<=Number;i++) { for(int j=-Number;j<=Number;j++) { float Weights=(1/(Sigma2*3.1415))*exp(-(j*j+i*i)/Sigma2); WeightsSum+=Weights; OutColor+=Weights*SceneTextureLookup(UV+float2(j/sW,i/sH),tIndex,false).xyz; } } OutColor/=WeightsSum; return float4(OutColor,1.0f);
群里朋友需要一个模糊贴图的于是又写了个
//5x5高斯模糊 //input UV 贴图UV //input Texture 传入TextureObject //input TexSize 图片大小,比如float2(512,512) int UVOfferset[]={-2,-1,0,1,2}; float Weights[]= { 0.0036,0.0146,0.0256,0.0146,0.0036, 0.0146,0.0586,0.0952,0.0586,0.0146, 0.0256,0.0952,0.1501,0.0952,0.0256, 0.0146,0.0586,0.0952,0.0586,0.0146, 0.0036,0.0146,0.0256,0.0146,0.0036 }; float3 OutColor={0.0,0.0,0.0}; for(int i=0;i<=4;i++) { for(int j=0;j<=4;j++) { OutColor+=Weights[i*5+j]*Texture2DSample(Texture, TextureSampler, UV+float2(UVOfferset[j]/TexSize.x,UVOfferset[i]/TexSize.y)); } } return float4(OutColor,1.0f);
//7x7均值模糊 //input UV 贴图UV //input Texture 传入TextureObject //input TexSize 图片大小,比如float2(512,512) int UVOfferset[]={-3,-2,-1,0,1,2,3}; float Weights[]= { 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1, 1,1,1,1,1,1,1 }; float3 OutColor={0.0,0.0,0.0}; for(int i=0;i<=6;i++) { for(int j=0;j<=6;j++) { OutColor+=Weights[i*7+j]*Texture2DSample(Texture, TextureSampler, UV+float2(UVOfferset[j]/TexSize.x,UVOfferset[i]/TexSize.y)); } } return float4(OutColor,1.0f)/49;