penumbra icon indicating copy to clipboard operation
penumbra copied to clipboard

Penumbra with RenderTarget2D and PointClamp sampler state

Open matt-clegg opened this issue 5 years ago • 2 comments

I'm rendering my game to a scaled down render target, which I then render at the full window size. It seems that penumbra doesn't want to work when I use a render target.

Here's some pseudo code showing my setup:

// Initialize Penumbra, some lights and hulls.
new PenumbraComponent();

// Create a render target 
RenderTarget2D renderTarget = new RenderTarget2D(GraphicsDevice, WindowWidth / 2, WindowHeight / 2);


// Inside the draw method...
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.Clear(Color.White);

spriteBatch.begin(samplerState: SamplerState.PointClamp);

// DO GAME DRAWING HERE

spruteBatch.End();

GraphicsDevice.SetRenderTarget(null);
penumbra.BeginDraw();

spriteBatch.Begin(samplerState: SamplerState.PointClamp);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, WindowWidth, WindowHeight), Color.White);

spriteBatch.End();
penumbra.Draw(gameTime);

This resulted in the lighting rendered at the original scale of the render target, and the game at the scaled size: scaled lights

To overcome this, I scaled up the positions of all hulls and lights by 2 (the render target is half the window size). This seemed to fix it, but then I saw the SamplerState.PointClamp wasn't working.

This is what the game looks like without lighting: no lights

And with lighting: lighting

It's turned blurry, as if the PointClamp filter was disabled.

Are there any ways to overcome this issue? Would it be possible to allow penumbra to render to the same RenderTarget the game is drawn to, allowing it to be scaled up correctly, with the PointClamp sampler state?

matt-clegg avatar Nov 23 '18 18:11 matt-clegg

Hey @matt-clegg, thanks for bringing out this issue! This indeed seems to be a limitation of Penumbra and it'd be nice if we could find a nice solution for this scenario.

Penumbra is internally also operating with custom render targets. It recreates the render targets only on window size changes and it always matches the size of back buffer. You are drawing on a custom render target with a different size and this info is currently not picked up by Penumbra. One solution I see is to, instead of using back buffer size, use the size of last set render target.

Before I move forward with this, can you try the following:

  1. Instead of using the NuGet package of Penumbra, clone the repo and reference the project directly.
  2. Modify the following lines in Penumbra source for render target creation to match the size of your render target: https://github.com/discosultan/penumbra/blob/3caf48a793e4993e16c1f0f52da6fe4388468753/Source/Graphics/Providers/TextureProvider.cs#L71-L76

See if that makes a difference (without you having to scale hulls nor lights).

If that doesn't work, perhaps you can share a demo of the issue and I can try debugging it myself.

discosultan avatar Nov 23 '18 20:11 discosultan

See https://github.com/discosultan/penumbra/issues/20 for a potential workaround.

discosultan avatar Apr 05 '19 08:04 discosultan