【问题标题】:How do you write a vertex shader that does nothing?你如何编写一个什么都不做的顶点着色器?
【发布时间】:2012-10-11 03:09:56
【问题描述】:

尽管我面临的问题很简单,但我在互联网上的任何地方都找不到答案。我有一个从我正在使用的 RenderTarget 获得的源纹理,然后我将其传递给我的效果。我的效果有一个顶点着色器和一个像素着色器,但像素着色器是重要的。我希望顶点着色器对输入顶点完全不做任何事情。然后输出应该被传递给我的像素着色器,它将对图像执行图像处理(如模糊等)。其结果将被绘制到屏幕上。

所以基本上,我只想要一个顶点着色器,它可以将纹理输入并完全原封不动地传递出去。这里没有 3D 几何可言。

这是我为此编写的代码:


float4 VSBasic(float4 vin : POSITION) : POSITION
{
    return vin;
}

这是我的像素着色器,它应该将所有像素变为红色:


float4 PS_GaussianBlur(float2 texCoord : TEXCOORD) : COLOR0
{
    float4 color = float4(0.0f, 0.0f, 0.0f, 1.0f);

    //int kernelLength = min(31, kernelRadius * 2 + 1);
    //for (int i = 0; i &lt kernelLength; i++)
        //color += tex2D(colorMap, texCoord + offsets[i]) * kernel[i];

    color = float4(1.0f, 0.0f, 0.0f, 1.0f);
    return color;
}

请注意,模糊部分已被注释掉以进行测试。

那我做错了什么??!

附:我什至使用顶点着色器的唯一原因是因为 XNA 会抱怨我正在使用冲突的像素/顶点着色器版本,除非我指定我应该编译 PS_3_0 和 VS_3_0(因为我需要 PS_3_0,我在 PS_2_0 中没有顶点着色器)。因此,如果有不同的方法来指定顶点着色器版本而不实际实现顶点着色器,请告诉我。

编辑:澄清一下,我的解决方案在 PS_2_0 中效果很好,但我认为 PS_2_0 没有足够的常量寄存器。我想要做的是将我的着色器扩展到 PS_3_0 以便我可以使用更多的寄存器。然而,当我这样做时,XNA 抱怨 PS_3_0 不向后兼容较低的顶点着色器,所以我不得不制作自己的顶点着色器。但是,我不希望这个顶点着色器做任何事情,因为所有的工作都是在我的像素着色器中完成的。我希望这能解决问题。

【问题讨论】:

  • 你能澄清一下这个问题吗?当前的解决方案是否有效?为什么它不适合您?
  • 你确定这是 C# 吗?代码似乎不是 C#。
  • 这是 HLSL。我删除了 C# 标签。 XNA 是 C#,但问题根本与 C# 无关。
  • @AndrewRussell,谢谢。我对所有的冒号感到困惑:)

标签: xna hlsl


【解决方案1】:

我不知道你做错了什么,因为你还没有说你是如何渲染的。我假设您使用的是SpriteBatch,这是一个坐标系问题。

您可以在the XNA Stock Effects 下载中找到SpriteBatch 内部使用的着色器。

你会注意到它有一个投影变换。您将坐标输入到客户空间中的SpriteBatch。但渲染实际上发生在光栅空间(投影矩阵将顶点转换到这个空间)。

客户端空间从左上角的 (0,0) 到视口右下角的 (width,height)。

投影空间从左下角的 (-1,-1) 到视口右上角的 (1,1)。

通常,对于全屏效果,最简单的方法是简单地渲染到覆盖光栅空间的固定四边形(即:不要使用SpriteBatch,而是使用顶点缓冲区)。你不需要任何投影矩阵,你的顶点着色器可以是空的。

如果您确实想使用SpriteBatch,阅读This blog post 可能会很有用。请注意,顶点着色器的代码实际上是错误的——它不包括投影变换。

另外,我怀疑你没有通过你的着色器传递TEXCOORD0(也许是COLOR0)会是一个问题。

【讨论】:

  • 我正在使用 SpriteBatch 进行绘制,并且我想保持这种方式,以便我可以旋转、缩放和着色通过我的着色器运行的任何图像(通过 sprite 批处理非常容易) .我尝试将输入顶点乘以顶点着色器中的视图和投影矩阵,但仍然失败,仅供参考
  • 在您链接的博客文章中搜索了 cmets 后,我找到了答案!非常感谢安德鲁。如果你有时间,我有一个简单的问题。我有一个名为内核的 float[]。为什么在循环中使用 if(kernel[i] != 0) 会显着增加使用的寄存器数量?
  • 我不确定。可能最好在一个更详细的新问题中提出这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多