Xna HLSL 3可以单独声明像素着色器吗?

Xna HLSL 3可以单独声明像素着色器吗?,xna,shader,hlsl,Xna,Shader,Hlsl,我被要求将以下问题分成多个问题: 这是问第一个问题,我可以在HLSL 3中运行没有顶点着色器的像素着色器吗。在HLSL 2中,我注意到您可以,但我似乎无法在3中找到方法 着色器将很好地编译,但是在调用SpriteBatch Draw()时,我将从Visual Studio获得此错误 无法将着色器模型3.0与早期的着色器模型混合使用。如果顶点着色器或像素着色器编译为3.0,则两者必须同时使用 我不相信我在着色器中定义了任何东西来使用3之前的任何东西。所以我有点困惑。任何帮助都将不胜感激。问题在于

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

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

着色器将很好地编译,但是在调用SpriteBatch Draw()时,我将从Visual Studio获得此错误

无法将着色器模型3.0与早期的着色器模型混合使用。如果顶点着色器或像素着色器编译为3.0,则两者必须同时使用


我不相信我在着色器中定义了任何东西来使用3之前的任何东西。所以我有点困惑。任何帮助都将不胜感激。

问题在于内置的
SpriteBatch
着色器是2.0。如果仅指定像素着色器,
SpriteBatch
仍使用其内置顶点着色器。因此,版本不匹配

那么,解决方案就是自己指定一个顶点着色器。幸运的是,微软提供了最新的解决方案。它所涉及的只是一个矩阵变换。这是经过修改的代码,您可以直接使用:

float4x4 MatrixTransform;

void SpriteVertexShader(inout float4 color    : COLOR0,
                        inout float2 texCoord : TEXCOORD0,
                        inout float4 position : SV_Position)
{
    position = mul(position, MatrixTransform);
}
然后-因为
SpriteBatch
不会为您设置它-正确设置效果的
MatrixTransform
。这是“客户”空间的简单投影(来源于)。代码如下:

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);

你可以试试简单的例子。灰度着色器是了解最小像素着色器如何工作的一个非常好的示例

基本上,您可以在内容项目下创建如下效果:

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();
    }
}
您还需要:

  • 创建效果对象并加载其内容

    环境影响=内容负荷(“影响/环境”)

  • 调用SpriteBatch.Begin()方法传递要使用的效果对象

    spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, 无效的 无效的 无效的 环境效应, camera2d.GetTransformation())

  • 在SpriteBatch.Begin()-SpriteBatch.End()块中,必须调用效果内部的技术

    ambienceEffect.CurrentTechnical.Passes[0]。Apply()


  • 别忘了“VertexShader=compile vs_3_0 SpriteVertexShader();”“vs”vs“ps”让我看了一会儿!(回答得很好,帮助你还是另一种方式?@Lodewijk独立发表——我以前没有看过那篇博文(尽管他的发表日期早几个月)。这并不奇怪,他们几乎是一样的-似乎我们都使用了相同的源材料(见我的链接)。谢谢你的回答。看到一些代码集有这样的生活是很有趣的,它们一直在博客上流传。同时也很奇怪。