Estoy tratando de aplicar fog of war a las áreas en la pantalla que el jugador no puede ver actualmente. Lo hago presentando el contenido del juego en un RenderTarget
y la niebla de la guerra en otro, y luego los fusiono con un archivo de efectos que toma el color del juego RenderTarget
y el alfa del objetivo de renderizado fog of war. El FOW RenderTarget
es negro donde aparece el FOW y blanco donde no aparece.Uso de Effect For Fog of War
Esto funciona, pero colorea la niebla de guerra (las ubicaciones no reveladas) de color blanco en lugar del color deseado de negro.
Antes de aplicar el efecto borro el backbuffer del dispositivo a blanco. Cuando trato de borrarlo a negro, no aparece nada de la niebla de la guerra, que supongo que es un producto de mezcla alfa con negro. Sin embargo, funciona para todos los demás colores, dando a la pantalla resultante una tonalidad de ese color.
¿Cómo puedo crear una niebla negra mientras sigo siendo capaz de hacer mezclas alfa entre los dos objetivos de renderizado?
El código de representación para la aplicación de la 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();
}
El archivo de efectos que estoy usando para aplicar el 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();
}
}
Muy útil respuesta. Tenía los conceptos de alfa y mezcla mal. Mi LightTarget RT ahora es transparente en las áreas visibles y totalmente negro opaco en todos lados. Eso me permite usar una versión modificada de tu sombreador para dibujar el fow. En lugar de color.r * (1-fow.a) estoy usando fow.r * (1-fow.a). –