问题是,当我尝试在精灵批次中绘制前一个渲染目标的纹理时,每个通道都被应用。在精灵批次中应用通行证似乎不起作用。
我发现的一个解决方案是将每个通道移动到它自己的技术中,但这不是多通道效果应该实现的方式。如何在精灵批次中只应用一次技术?
我正在尝试做一个多通道效果,用阴影和高光绘制一个窗口边框。
在Pass0中,顶点缓冲区设置为形状中的顶点。顶点着色器将顶点转换为屏幕空间,像素着色器使用 FillColor 填充形状。
在Pass1中,第一遍的渲染目标用于此遍的像素着色器。现在它只是将其设置为用于调试的颜色。最后,它将使用 TEXCOORDn 语义和采样器获取相邻像素的颜色。
最后一个通道Pass2与 Pass1 完全相同,只是它检查不同的颜色并在阴影下方放置一个高光。
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();
}
}