【发布时间】:2012-10-10 16:00:45
【问题描述】:
我正在尝试在 Texture2D 上实现高斯模糊,但在寻找任何好的教程等方面遇到了麻烦。
我终于设法找到了一段不错的一次性示例代码,它明显使图像模糊了一点,但我希望能够随着时间的推移使其变得更模糊和更少模糊,我不充分了解高斯模糊的工作原理以实现这一点。
我想这一定与 PixelKernel 和 BlurWeights 有关,但我真的不知道这些值的用途/更改它们的作用。
所以我的问题基本上是:
这是在 HLSL/XNA 中进行高斯模糊的好方法吗?如果是这样,我如何使场景更模糊?作为额外的奖励,您能否指出我对高斯模糊在着色器上下文中如何工作的一个很好的解释?
感谢您的宝贵时间,
TS
附言
刚刚意识到我应该包含代码:
sampler2D Tex0;
float TintColour;
int TexHeight = 640;
int TexWidth = 480;
const int KernelSize = 7;
float2 PixelKernel[7] =
{
{-3, 0},
{-2, 0},
{-1, 0},
{0, 0},
{1, 0},
{2, 0},
{3, 0},
};
const float BlurWeights[7] =
{
0.064759,
0.120985,
0.176033,
0.199471,
0.176033,
0.120985,
0.064759,
};
struct VertexShaderOutput
{
float2 TexCoord0 : TEXCOORD0;
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 colour = 0;
float2 TexSize = float2(1.0/TexHeight, 1.0/TexWidth);
for(int p = 0; p < 7; p++)
{
colour += tex2D(Tex0, input.TexCoord0 + (PixelKernel[p] * TexSize)) * BlurWeights[p];
}
colour.a = 1.0f;
return colour;
}
technique Technique1
{
pass Pass1
{
// TODO: set renderstates here.
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
【问题讨论】:
-
看看3D Graphics with XNA Game Studio 4.0,第 2 章和第 8 章,尤其是 pg.214。
-
要获得任何类型的强/宽和正确的模糊,您需要一个 2-pass 效果。一次通过不能采样足够多的像素(当然也不能足够快);两遍将复杂度从 n^2 降低到 2n,从而允许更大的采样区域和更强的模糊。
-
嗯,好的@peachykeen 感谢您的回复,我听说 2-pass 方式更有效更好,但我在任何地方都找不到很好的教程/示例 - 特别是对于 HLSL(因为我以前没有在 HLSL 中做过多通道的东西)。
-
XNA 可以为您处理大部分杂乱的部分(多个表面等),并且实际的 HLSL 代码非常简单。这个想法是先垂直模糊,然后水平模糊;因为复杂度是 2n,你可以用 20 个样本模糊 10 个像素的半径(单次通过 100 个)。我在这里从旧着色器中提取了一些基本代码:pastebin.com/eBf0W9F1,但还有许多其他实现。如果您正在处理绽放或景深效果,则可以添加前置通道和后通道。可以重复这些通道以获得更多模糊效果。
-
注意:刚刚注意到我发布的 sn-p 是使用间隔样本。抓住了错误的一对传球,这些传球意味着第二次(甚至更广泛)模糊运行。您通常希望使用 1/2/3/4(而不是给定的 1/3/5/7)进行初始模糊。
标签: xna-4.0 blur hlsl gaussian pixel-shader