HLSL 3 像素着色器能够单独声明吗?

3

我被要求将以下问题拆分为多个问题:

HLSL和Pix的问题数量

这是在问第一个问题,我是否可以在HLSL 3中运行像素着色器而没有顶点着色器。在HLSL 2中,我注意到可以,但是在3中似乎找不到方法?

着色器将编译成功,但是当调用SpriteBatch Draw()时,我会收到来自Visual Studio的以下错误。

“不能混合着色器模型3.0和早期的着色器模型。如果顶点着色器或像素着色器被编译为3.0,则它们必须都是。”

我不认为我已经定义了任何使用早期版本的内容。所以我有点困惑。任何帮助都将不胜感激。

2个回答

7
问题在于内置的SpriteBatch着色器是2.0版本。如果只指定像素着色器,SpriteBatch仍然使用其内置的顶点着色器。因此版本不匹配。
解决方案是自己指定一个顶点着色器。幸运的是,微软提供了XNA内置着色器的源代码。它只涉及矩阵变换。这里是修改后可以直接使用的代码:
float4x4 MatrixTransform;

void SpriteVertexShader(inout float4 color    : COLOR0,
                        inout float2 texCoord : TEXCOORD0,
                        inout float4 position : SV_Position)
{
    position = mul(position, MatrixTransform);
}

然后 - 因为 SpriteBatch 不会为您设置它 - 正确设置您的效果的 MatrixTransform。这是“客户端”空间的简单投影(源自 this blog post)。以下是代码:

Matrix projection = Matrix.CreateOrthographicOffCenter(0, 
        GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1);
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
effect.Parameters["MatrixTransform"].SetValue(halfPixelOffset * projection);

1
不要忘记“VertexShader = compile vs_3_0 SpriteVertexShader();”我刚才漏看了一会儿“vs”和“ps”!(回答很好,http://gamedev.sleptlate.org/blog/165-implementing-a-pass-through-3vertex-shader-for-games-without-vertices/是帮助你还是反过来帮助其他人的?) - Lodewijk
@Lodewijk 独立地 - 我之前没有看过那篇博客文章(尽管他的发布日期早于几个月)。他们几乎完全相同并不令人惊讶 - 看起来我们都使用了相同的来源材料(请参见我的链接)。 - Andrew Russell
谢谢你的回答。看到一些代码集一直在博客中传播,这真是有趣。同时也很奇特。 - Lodewijk

-2

您可以在这里尝试简单的示例。灰度着色器是一个非常好的例子,可以帮助您了解最小像素着色器的工作原理。

基本上,您可以在内容项目下创建一个效果,就像这个:

sampler s0;

float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
    // B/N
    //float4 color = tex2D(s0, coords);
    //color.gb = color.r;

    // Transparent
    float4 color = tex2D(s0, coords);
    return color;
}

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

你还需要:

  1. 创建一个Effect对象并加载它的内容。

    ambienceEffect = Content.Load("Effects/Ambient");

  2. 调用SpriteBatch.Begin()方法,并传入要使用的Effect对象。

    spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, null, null, null, ambienceEffect, camera2d.GetTransformation());

  3. 在SpriteBatch.Begin() - SpriteBatch.End()块中,必须调用Effect内的Technique

    ambienceEffect.CurrentTechnique.Passes[0].Apply();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接