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

时间:2013-02-08 13:28:37

标签: xna shader hlsl

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

HLSL and Pix number of questions

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

着色器编译正常,然后我会在调用SpriteBatch Draw()时从Visual Studio中得到此错误。

“无法将着色器模型3.0与早期着色器模型混合使用。如果顶点着色器或像素着色器编译为3.0,则它们必须都是。”

我不相信我已经在着色器中定义了任何早于3的东西。所以我有点困惑。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:7)

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

然后,解决方案是自己指定顶点着色器。幸运的是,Microsoft提供了source to XNA's built-in shaders。所涉及的只是矩阵变换。这是修改后的代码,您可以直接使用它:

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 :(得分:-2)

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

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

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. 创建一个效果对象并加载其内容。

    ambienceEffect = Content.Load(“Effects / Ambient”);

  2. 调用SpriteBatch.Begin()方法传递要使用的Effect对象

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

  3. 在SpriteBatch.Begin() - SpriteBatch.End()块中,你必须在效果中调用技术

    ambienceEffect.CurrentTechnique.Passes [0]。适用();