我一直在尝试在Monogame中实现一些非常基本的照明,我在网上找到了几个教程(即这里):
https://gamedev.stackexchange.com/questions/40563/how-can-i-acheive-a-smooth-2d-lighting-effect
我试图复制他们的方法,但一直没有成功,希望有人能告诉我原因。
我加载了一个光掩模纹理(与第一个链接中相同),一个用于测试光照的简单对象和我的效果文件(这些已在类中进一步声明):
lightMask = ScreenManager.Instance.Content.Load<Texture2D>("Sprites\\Effects\\LightMask");
cursor = ScreenManager.Instance.Content.Load<Texture2D>("Sprites\\UI\\Cursor");
effect = ScreenManager.Instance.Content.Load<Effect>("Effects\\LightEffect");
我在这里初始化它们:
GraphicsDevice graphicsDevice = ScreenManager.Instance.GraphicsDeviceManager.GraphicsDevice;
var pp = graphicsDevice.PresentationParameters;
lightsTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);
mainTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);
并在此处绘制所有内容:
GraphicsDevice graphicsDevice = ScreenManager.Instance.GraphicsDeviceManager.GraphicsDevice;
graphicsDevice.SetRenderTarget(lightsTarget);
graphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive);
spriteBatch.Draw(lightMask, ScreenCentre - new Vector2(128), Color.White);
spriteBatch.End();
graphicsDevice.SetRenderTarget(mainTarget);
graphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
spriteBatch.Draw(cursor, ScreenCentre - new Vector2(64), Color.White);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);
graphicsDevice.Clear(Color.Black);
effect.Parameters["LightMask"].SetValue(lightsTarget);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
effect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Draw(mainTarget, Vector2.Zero, Color.White);
spriteBatch.End();
(-new Vector2(128)和-new Vector(64)只是将精灵置于屏幕中间)。
这是我的效果文件:
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
sampler2D TextureSampler : register(s0);
Texture2D LightMask;
sampler2D LightMaskSampler = sampler_state { Texture = <LightMask>; };
float4 MainPS(float4 position : SV_POSITION, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
float4 lightColour = tex2D(LightMaskSampler, texCoord);
float4 tex = tex2D(TextureSampler, texCoord);
return lightColour * tex;
}
technique SpriteDrawing
{
pass Pass1
{
PixelShader = compile ps_5_0 MainPS();
}
};
代码有点杂乱无章,因为我只想让这个有用。据我所知,我已经正确设置了一切,但我看到的只是黑屏。
当我在没有效果的情况下单独绘制每个渲染状态时,我确实看到每个纹理都在正确的位置,所以看起来我的着色器没有正确地将它们组合在一起。
任何可以解决这个问题的光(廉价笑话)都会受到高度赞赏。