【问题标题】:HLSL 3 Can a Pixel Shader be declared alone?HLSL 3 可以单独声明像素着色器吗?
【发布时间】:2013-02-08 13:28:36
【问题描述】:

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

HLSL and Pix number of questions

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

着色器可以正常编译,但是在调用 SpriteBatch Draw() 时,我会从 Visual Studio 收到此错误。

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

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

【问题讨论】:

    标签: xna shader hlsl


    【解决方案1】:

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

    因此,解决方案是自己也指定一个顶点着色器。幸运的是微软提供了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);
    

    【讨论】:

    • 别忘了“VertexShader = compile vs_3_0 SpriteVertexShader();” 'vs' vs 'ps' 一时闪过我的视线! (虽然很好的答案,gamedev.sleptlate.org/blog/… 帮助你还是反过来?)
    • @Lodewijk 独立 - 我之前没有看过那篇博文(尽管他的发布日期比他早几个月)。它们几乎相同并不奇怪 - 看来我们都使用了相同的源材料(请参阅我的链接)。
    • 感谢您的回答。看到一些代码集有这样的生活很有趣,一直在博客中传播。同时非常奇特。
    【解决方案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. 创建一个 Effect 对象并加载其内容。

      ambienceEffect = Content.Load("效果/环境");

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

      spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, 空值, 空值, 空值, 氛围效果, camera2d.GetTransformation());

    3. 在 SpriteBatch.Begin() - SpriteBatch.End() 块内,您必须在 Effect 内调用技术

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      相关资源
      最近更新 更多