MonoGame: буфер трафарета не работает

Я пытаюсь добавить тени в свою 2D-игру на основе MonoGame. Сначала я просто рендерил полупрозрачные черные текстуры на кадр, но они иногда накладываются друг на друга, и это выглядит противно:

Пример рендеринга с перекрывающимися тенями

Я попытался сначала отрендерить все тени в буфер трафарета, а затем использовать одну полупрозрачную текстуру для одновременного отрисовки всех теней с помощью буфера трафарета. Однако это не работает так, как ожидалось:

Визуализация буфера трафарета

Две проблемы:

  • Тени визуализируются в сцене
  • Буфер трафарета, похоже, не пострадал: полупрозрачная черная текстура покрывает весь экран.

Вот код инициализации:

StencilCreator = new DepthStencilState
{
    StencilEnable = true,
    StencilFunction = CompareFunction.Always,
    StencilPass = StencilOperation.Replace,
    ReferenceStencil = 1
};

StencilRenderer = new DepthStencilState
{
    StencilEnable = true,
    StencilFunction = CompareFunction.Equal,
    ReferenceStencil = 1,
    StencilPass = StencilOperation.Keep
};

var projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1); 
var halfPixel = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

AlphaEffect = new AlphaTestEffect(GraphicsDevice)
{
    DiffuseColor = Color.White.ToVector3(),
    AlphaFunction = CompareFunction.Greater,
    ReferenceAlpha = 0,
    World = Matrix.Identity,
    View = Matrix.Identity,
    Projection = halfPixel * projection
};

MaskingTexture = new Texture2D(GameEngine.GraphicsDevice, 1, 1);
MaskingTexture.SetData(new[] { new Color(0f, 0f, 0f, 0.3f) });

ShadowTexture = ResourceCache.Get<Texture2D>("Skins/Common/wall-shadow");

И следующий код является телом моего метода Draw:

// create stencil
GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0f, 0);
var batch = new SpriteBatch(GraphicsDevice);
batch.Begin(SpriteSortMode.Immediate, null, null, StencilCreator, null, AlphaEffect);
foreach (Vector2 loc in ShadowLocations)
{
    newBatch.Draw(
        ShadowTexture,
        loc,
        null,
        Color.White,
        0f,
        Vector2.Zero,
        2f,
        SpriteEffects.None,
        0f
    );
}
batch.End();

// render shadow texture through stencil
batch.Begin(SpriteSortMode.Immediate, null, null, StencilRenderer, null);
batch.Draw(MaskingTexture, GraphicsDevice.Viewport.Bounds, Color.White);
batch.End();

В чем может быть проблема? Тот же код отлично работал в моем проекте XNA.


person Impworks    schedule 25.02.2014    source источник


Ответы (1)


Я решил проблему, используя RenderTarget2D вместо буфера трафарета. Отрисовка сплошных черных теней на RT2D, а затем отрисовка самого RT2D в сцену полупрозрачным цветом делает свое дело и намного проще в реализации.

person Impworks    schedule 05.05.2014