penumbra
penumbra copied to clipboard
Penumbra with RenderTarget2D and PointClamp sampler state
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:
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:
And with 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?
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:
- Instead of using the NuGet package of Penumbra, clone the repo and reference the project directly.
- 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.
See https://github.com/discosultan/penumbra/issues/20 for a potential workaround.