【问题标题】:Trying to make Gaussian Blur stronger/blurrier - XNA 4.0 HLSL试图使高斯模糊更强/更模糊 - XNA 4.0 HLSL
【发布时间】: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


【解决方案1】:

这已经过时了,有人可能还在寻找答案,所以:

如果您想要一些可以在现代市场(虚幻引擎 3 - 4 和类似引擎)中具有竞争力的质量,那么解决方案是多通道 2 通道高斯模糊。

正如您被告知的那样,使用两遍高斯模糊来减少计算的复杂性。现在,当您有算法时,您想做的是在不同分辨率下多次通过,让我们从 3 开始。

制作全屏的 1/2 渲染目标,进行两次模糊,保留结果。 制作原始、模糊的 1/4 渲染目标。 将 1/8 渲染目标设为 origina,模糊。

每个都有不同的内核(使用更强的模糊来降低分辨率),现在您已经完成了将所有 RT 组合成质量不错的结果。

3 分辨率实际上有点老派,在虚幻引擎 3 (udk) 中用于绽放,虚幻引擎 4 使用 5 + 全分辨率缓冲区模糊正在考虑中。

当然你也可以考虑盒子模糊,我个人会使用大内核的多通道盒子模糊来减少总通过次数,但这需要一些测试。

【讨论】:

  • 感谢@user3821985 的信息 - 我设法让它与标准 XNA 框架一起工作,因为它可以很容易地在 c# 中获取 kinect 数据,但虚幻听起来像是一种很酷/更强大的方式去做(如果 kinect 数据可以直接访问)。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 2016-04-30
相关资源
最近更新 更多