DirectX10:将效果应用于纹理

时间:2013-12-04 01:01:25

标签: directx pixel-shader

我有一个纹理,它成为像素着色器的输入。

代码段:

mDevice->CreateShaderResourceView(myTexture, nullptr, byRef(mBckSRView));
...->AsShaderResource()->SetResource(mBckSRView);

但是,我想在着色器中使用模糊滤镜之前对其应用模糊滤镜。 我该怎么做?

1 个答案:

答案 0 :(得分:1)

  

我希望在着色器中使用模糊滤镜之前对其应用模糊滤镜。

     

但是,我还要添加其他效果

如何?

最简单的模糊,算法如下:在当前纹理元素周围采样多个纹素,并以您喜欢的任何方式组合它们的颜色:平均值,线性插值,乘以权重,高斯函数,所有这些的组合等。

当然,该算法是一种强力解决方案。有很多优化领域。但它很简单,对你来说足够了。如果没有,只需谷歌为您使用的语言提供所需的算法并阅读一些论文。

在哪儿?

  1. 您可以在像素着色器中执行此操作

    • 优点:您可以为每个帧的每个像素改变算法。只需重新加载或分支着色器。哇!
    • 缺点:采样是相当昂贵的操作,例如,您采样9或25或100个纹素而不是一个。
  2. 您可以在CPU端执行此操作:只需在创建资源之前(在加载之后但在CreateTexture2D和{{之前)将效果应用于原始位图数据本身(像素数组) 1}})。

    • 优点:你仍然可以在运行时改变算法;有可以为你完成所有工作的图书馆
    • 缺点:像素着色器保持不变,只有一个纹素被采样;
  3. 您可以离线应用效果,即在应用程序启动之前。让您的艺术家在Photoshop或GIMP中应用不同效果的一组纹理。或者使用脚本自动化它。

    • 优点:零运行时成本;零编程(艺术家的工作;))
    • 缺点:固定的效果集;更多要加载的资产
  4. 编辑:在着色器中组合复杂的多重采样效果。

    到目前为止一直很好,但是如果你想在着色器中组合效果怎么办?好吧,你只是在着色器代码中逐个应用它们:在第一个效果之后你有一个像素的颜色,你用它作为第二个效果的来源等。

    但是如果你想一个接一个地应用两种不同的模糊呢?模糊需要对源纹理的相邻像素进行采样,但我们只有当前像素。解决方案是渲染纹理并使用渲染纹理作为输入和第二个模糊着色器进行另一次传递(绘制调用)。

    EDIT2

      
        

    问题是如何将着色器应用于texture2d对象,该对象成为另一个着色器的输入

      

    我会尽力澄清。你至少有三个替代方案。简而言之:

    1. 直接在“另一个着色器”中进行操作,想象一下,不是采样,而是采样+应用第一个效果。以下是像素着色器的示例(但它可以是任何着色器阶段):

      CreateShaderResourceView
    2. 您无法将模糊应用为//pseudocode of example "multieffect" pixel shader Texture2D texture0; SamplerState defaultSampler; // first effect moved to function (surely it can be in main()'s body instead) float4 sampleAndApplyFirstEffect(Texture2D texture, SamplerState sampler, float2 texcoord, float effectParameters) { float4 rawColor = texture.Sample(sampler, texcoord); // sample original float4 color = ... // apply 1st effect's algo (you can use passed // effectParameters to customize it) return color; } // shader entry point float4 anotherShaderMain(PS_IN psin) { // instead of sampling you get output of your first effect // (it doesn't really need to be a separate function, // but that make things looks cleaner) float4 color = sampleAndApplyFirstEffect(texture0, defaultSampler, psin.texcoord, 200.0f); color *= 0.5f; // apply your second effect color = MyThirdEffect(color); // third effect, etc. return color; } "second effect",因为它需要多个纹素才能进行采样,但您只有一个作为第一效果的输出。为此,我们需要对整个纹理进行预处理。要实现这一点,您需要渲染到纹理并将第二个效果移动到第二遍:

      MyThirdEffect
    3. 如果可以,请使用Compute着色器并忘记以上所有=)

    4. 希望它有所帮助!