Kas*_*dum 9 .net c# xna effects
我正在尝试将战争雾应用于屏幕上当前对玩家不可见的区域.我通过将游戏内容渲染RenderTarget到另一个中并将战争迷雾渲染到另一个中来实现这一点,然后我将它们与效果文件合并,该效果文件从游戏中获取颜色RenderTarget并从战争雾渲染目标中获取alpha.FOW RenderTarget在FOW出现时为黑色,而在FOW出现时则为白色.
这确实有效,但它将战争的雾(未显示的位置)变成白色而不是黑色的预期颜色.
在应用效果之前,我将设备的后备缓冲区清除为白色.当我试图将它清除为黑色时,根本没有出现战争迷雾,我认为这是alpha混合黑色的产物.但它适用于所有其他颜色 - 为结果屏幕提供该颜色的色调.
如何在仍能够在两个渲染目标之间进行Alpha混合的同时实现黑雾?
应用FOW的渲染代码:
private RenderTarget2D mainTarget;
private RenderTarget2D lightTarget;
private void CombineRenderTargetsAndDraw()
{
batch.GraphicsDevice.SetRenderTarget(null);
batch.GraphicsDevice.Clear(Color.White);
fogOfWar.Parameters["LightsTexture"].SetValue(lightTarget);
batch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
fogOfWar.CurrentTechnique.Passes[0].Apply();
batch.Draw(
mainTarget,
new Rectangle(0, 0, batch.GraphicsDevice.PresentationParameters.BackBufferWidth, batch.GraphicsDevice.PresentationParameters.BackBufferHeight),
Color.White
);
batch.End();
}
Run Code Online (Sandbox Code Playgroud)
我用来应用FOW的效果文件:
texture LightsTexture;
sampler ColorSampler : register(s0);
sampler LightsSampler = sampler_state{
Texture = <LightsTexture>;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float2 tex = input.TexCoord;
float4 color = tex2D(ColorSampler, tex);
float4 alpha = tex2D(LightsSampler, tex);
return float4(color.r, color.g, color.b, alpha.r);
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
Run Code Online (Sandbox Code Playgroud)
我还没有深入研究 XNA,目前无法设置它来检查 4.0 的 CTP,但从阅读文档来看,您似乎在加倍。根据我的理解,BlendState.AlphaBlend这会导致SpriteBatch绘制的每个精灵进行 alpha 混合。
根据文档,它使用默认设置
\n\nColorSourceBlend = Blend.One,\nAlphaSourceBlend = Blend.One,\n\nColorDestinationBlend = Blend.InverseSourceAlpha,\nAlphaDestinationBlend = Blend.InverseSourceAlpha,\nRun Code Online (Sandbox Code Playgroud)\n\n这应该会产生以下影响:
\n\n\n\n\n一:颜色的每个分量乘以 (1, 1, 1, 1)。
\n\nInverseSourceAlpha:颜色的每个分量都乘以源的 alpha 值的倒数。这\n 可以表示为 (1 \xe2\x88\x92 As, 1 \xe2\x88\x92 As,\n 1 \xe2\x88\x92 As, 1 \xe2\x88\x92 As),其中 As 是alpha\n 目标值。
\n
因此,如果您正在使用,Blend.AlphaBlend您应该能够将后台缓冲区清除为黑色,然后仅渲染地图精灵,直接降低应该褪色的 Alpha。这应该简单地淡化被 FOW“覆盖”的贴图像素,使其与后台缓冲区的黑色进行 alpha 混合。
如果您想采用着色器方法,您可以在两个渲染目标之间的着色器中进行 alpha 混合。我对你到底想要如何混合的解释感到有点困惑。你说你想要阿尔法混合,但是你的FOW渲染目标在有雾的地方是黑色的,在没有雾的地方是白色的。如果您使用 Alpha 来控制混合,则根据您想要的外观,整个渲染目标的雾色应该是均匀的(或适当的纹理)。假设您想要黑雾,整个渲染目标的颜色应该为 (0, 0, 0),并且 alpha 值应该根据您想要显示它的位置而变化。
\n\n使用这种方法,您可以将着色器更改为如下所示:
\n\nfloat4 PixelShaderFunction(VertexShaderOutput input) : COLOR0\n{\n float2 tex = input.TexCoord;\n\n float4 color = tex2D(ColorSampler, tex);\n float4 fow = tex2D(LightsSampler, tex);\n\n // color * inverse of FOW alpha + FOW * FOW alpha\n return float4(color.r * (1-fow.a) + fow.r * fow.a,\n color.g * (1-fow.a) + fow.g * fow.a,\n color.b * (1-fow.a) + fow.b * fow.a,\n 1);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我已经有一段时间没有做过 HLSL 着色器了,但我确信它可以写得更容易。不管怎样,如果 FOW 是黑色的(并且后台缓冲区被清除为黑色,并且你没有将各种 alpha 混合的精灵堆叠在一起 - 请参阅 Joel 的答案),那么这种方法与直接设置没有什么不同地图精灵的 alpha 取决于是否有 FOW。
\n