1

问题是,当我尝试在精灵批次中绘制前一个渲染目标的纹理时,每个通道都被应用。在精灵批次中应用通行证似乎不起作用。

我发现的一个解决方案是将每个通道移动到它自己的技术中,但这不是多通道效果应该实现的方式。如何在精灵批次中只应用一次技术?

我正在尝试做一个多通道效果,用阴影和高光绘制一个窗口边框。

Pass0中,顶点缓冲区设置为形状中的顶点。顶点着色器将顶点转换为屏幕空间,像素着色器使用 FillColor 填充形状。

Pass0 图像

Pass1中,第一遍的渲染目标用于此遍的像素着色器。现在它只是将其设置为用于调试的颜色。最后,它将使用 TEXCOORDn 语义和采样器获取相邻像素的颜色。

第 1 张图片

最后一个通道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