1

問題は、スプライト バッチで前のレンダー ターゲットのテクスチャを描画しようとすると、すべてのパスが適用されることです。スプライト バッチでパスを適用してもうまくいかないようです。

私が見つけた 1 つの解決策は、各パスを独自の手法に移行することですが、それはマルチパス効果を実現する方法ではありません。スプライト バッチでテクニックのパスを 1 つだけ適用するにはどうすればよいですか?

シャドウとハイライトでウィンドウの境界線を描画するマルチパス エフェクトを実行しようとしています。

Pass0では、頂点バッファーがシェイプ内の頂点に設定されます頂点シェーダーは頂点を画面空間に変換し、ピクセル シェーダーは FillColor で形状を塗りつぶします。

Pass0 画像

Pass1では、最初のパスのレンダー ターゲットがこのパスのピクセル シェーダーで使用されます。現在、デバッグ用の色に設定されています。最後に、TEXCOORDn セマンティックとサンプラーを使用して、隣接するピクセルの色を取得します。

Pass1 画像

最後のパスであるPass2は、Pass1とまったく同じですが、異なる色をチェックし、影の下にハイライトを配置します。

Pass2 画像

Window.cs Window::Draw

public void Draw(MainGame game) {
    Matrix vp = game.view * projection;
    game.GraphicsDevice.SetRenderTarget(target[0]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.GraphicsDevice.SetVertexBuffer(vertexbuffer);
    game.effect.Parameters["VPMatrix"].SetValue(vp);
    game.effect.Parameters["FillColor"].SetValue(new float[] { 103, 103, 103, 255 });
    game.effect.CurrentTechnique = game.effect.Techniques["Border"];
    game.effect.CurrentTechnique.Passes[0].Apply();
    game.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

    game.GraphicsDevice.SetRenderTarget(target[1]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, game.effect);
    game.effect.CurrentTechnique.Passes[1].Apply();
    game.spriteBatch.Draw(target[0], Vector2.Zero, Color.White);
    game.spriteBatch.End();

    game.GraphicsDevice.SetRenderTarget(target[0]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, game.effect);
    game.effect.CurrentTechnique.Passes[2].Apply();
    game.spriteBatch.Draw(target[1], Vector2.Zero, Color.White);
    game.spriteBatch.End();

    game.GraphicsDevice.SetRenderTarget(game.backBuffer);
    game.spriteBatch.Begin();
    game.spriteBatch.Draw(target[0], rectangle, Color.White);
    game.spriteBatch.End();
}

ウィンドウ.fx

float4x4 VPMatrix : register(c0);
float4 FillColor : register(c4);
float2 SHPercent : register(c5) = { 0.36893203883495145631067961165049, 1.262135922330097087378640776699 };
sampler ShapeSampler : register(s0) = sampler_state{ };

struct Fill_VS_Input {
    float4 position : POSITION0;
};

struct Fill_PS_Input {
    float4 position : POSITION0;
};

struct Shadow_PS_Input {
    float4 position : TEXCOORD0;
};

struct Highlight_PS_Input {
    float4 position : TEXCOORD0;
};

float4 ClampColor(float4 color) {
    return float4(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
}

float4 ShiftValue(float4 color, float percent) {
    return float4(clamp(color[0] * percent, 0, 1), clamp(color[1] * percent, 0, 1), clamp(color[2] * percent, 0, 1), 1);
}

Fill_PS_Input Fill_VS(Fill_VS_Input input) {
    Fill_PS_Input output;
    output.position = mul(input.position, VPMatrix);
    return output;
}

float4 Fill_PS(Fill_PS_Input input) : COLOR0 {
    return ClampColor(FillColor);
}

float4 Shadow_PS(Shadow_PS_Input input) : COLOR0 {
    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y))[3] == 0)
        return float4(0, 255, 0, 255);

    /*if (input.position.x == 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.x == 1)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.y == 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.y == 1)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y - 1))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x + 1, input.position.y))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y + 1))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x - 1, input.position.y))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);*/

    return float4(255, 0, 0, 255);
}

float4 Highlight_PS(Highlight_PS_Input input) : COLOR0 {
    return tex2D(ShapeSampler, float2(input.position.x, input.position.y)).rbga;
}

technique Border {
    pass Pass0 {
        VertexShader = compile vs_2_0 Fill_VS();
        PixelShader = compile ps_2_0 Fill_PS();
    }

    pass Pass1 {
        PixelShader = compile ps_2_0 Shadow_PS();
    }

    pass Pass2 {
        PixelShader = compile ps_2_0 Highlight_PS();
    }
}
4

0 に答える 0