BackBuffer and RenderTarget at one pass?

More
3 years 7 months ago - 3 years 7 months ago #1 by Fu-Bama
Is it possible to write to two outputs at one pass?

I'm trying to make interlaced effect, but current solution has two full-screen resolution render targets.
One to bypass effect and get raw BackBuffer image stored,
second to write that stored raw BackBuffer at the end of the shader to get previous frame without any effects applied.



Code:
Warning: Spoiler!
Last edit: 3 years 7 months ago by Fu-Bama.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #2 by Marty McFly
Replied by Marty McFly on topic BackBuffer and RenderTarget at one pass?
See MXAO code on official github repository how to write to multiple render targets (first pass writes to 3), only limitation is that they have to be of the same resolution. If it's possible to write to backbuffer + other textures, I never checked.
Also:

int(ReShade::ScreenSize.y * UvCoord.y)

is vpos.y.
Last edit: 3 years 7 months ago by Marty McFly.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #3 by crosire
Replied by crosire on topic BackBuffer and RenderTarget at one pass?
It's possible to write to multiple textures in one pass. It's not possible to write to the backbuffer and textures at the same time.

Additional documentation beside the code Marty mentioned is here (see the "RenderTarget" pass state):
github.com/crosire/reshade-shaders/blob/...ERENCE.md#techniques
Last edit: 3 years 7 months ago by crosire.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #4 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?
I just noticed that vpos : SV_Position is vertically reversed on OpenGL. Is it a bug? It's counting from the bottom to top at Y channel.
Last edit: 3 years 7 months ago by Fu-Bama.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #5 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?
Thanks for response. :)

Since it's interlaced shader we don't need full-res render targets, only half vertical resolution.
Even better, we can squeeze both render target outputs into one texture of a screen size.
But hey, if we flip flop write Back Buffer odd rows between top and bottom half of the Render Target, the previous frame will survive till second pass. And we can get rid of the third pass.
I managed to reduce it to 2 passes and one render target.

Here's how the render target looks like:


It flip flops current and previous frame from top to bottom at every frame.

The code:
Warning: Spoiler!
Last edit: 3 years 7 months ago by Fu-Bama.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #6 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?
For some reason it does not work in Assetto Corsa and Alien Isolation. Looks like it does not read the Render Buffer, every odd row is black.
But it works in Mirrors Edge (2007), RAGE and Blender. :huh:
EDIT*
It looks like
ClearRenderTargets = false;
is not working for those :(
Last edit: 3 years 7 months ago by Fu-Bama.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago #7 by crosire
Replied by crosire on topic BackBuffer and RenderTarget at one pass?

I just noticed that vpos : SV_Position is vertically reversed on OpenGL. Is it a bug? It's counting from the bottom to top at Y channel.

This is expected. OpenGL has its origin at the bottom left corner of the screen, while DirectX has its origin at the top left corner. ReShade fixes texture coordinates to match DirectX terminology, but doesn't do so for positions.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #8 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?
It looks like DirectX 10 games are clearing render targets, ignoring ClearRenderTargets = false;
When you un-comment at line 57 where there is // Preview RenderTarget you can see flip flop flashing of black texture when in DX10. That means the game does not preserve data from previous shader run, but clears it. Can it be fixed?
Last edit: 3 years 7 months ago by Fu-Bama.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #9 by Marty McFly
Replied by Marty McFly on topic BackBuffer and RenderTarget at one pass?
Hm. InterlacedTargetPass reads from InterlacedTargetBuffer and writes to it at the same time, that shouldn't be possible to work. That works for backbuffer only iirc. You still need pingpong textures.
Last edit: 3 years 7 months ago by Marty McFly.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago #10 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?

Hm. InterlacedTargetPass reads from InterlacedTargetBuffer and writes to it at the same time (...)

Reading from InterlacedTargetBuffer is not necessary in that pass. If I could just leave one half of the target untouched in the memory. BlendEnable = true in pass settings suppose to do that, right? Blend the render target with whatever was present in memory?
But I have no idea how to use it. I don't quite get it from the documentation. github.com/crosire/reshade-shaders/blob/...ERENCE.md#techniques

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #11 by Marty McFly
Replied by Marty McFly on topic BackBuffer and RenderTarget at one pass?
Correct. I've never really bothered with blending states as I find them quite fiddly, but in theory this should work:
BlendEnable = true; //to enable blending
BlendOp = ADD; //mimic lerp, A*(1-k) + B*k, where B is current data, A is previous
SrcBlend = SRCALPHA; //B*k so if alpha == 1 we get output of your pass, Src being output of current frame
DestBlend = INVSRCALPHA; //A*(1-k) so if alpha == 0 we get what was originally in the buffer (Dest being previous data)
Now you only need to set the alpha channel value of the pixels you want to change to 1 and leave the rest at 0. Haven't checked if this works but it should. ReShade has a bug with blending states, unsure if it's in the public build already so...
Last edit: 3 years 7 months ago by Marty McFly.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago #12 by crosire
Replied by crosire on topic BackBuffer and RenderTarget at one pass?
The fix for blending not working correctly was part of 3.1.1, so it's public.

Please Log in or Create an account to join the conversation.

More
3 years 7 months ago - 3 years 7 months ago #13 by Fu-Bama
Replied by Fu-Bama on topic BackBuffer and RenderTarget at one pass?
Yes it works :cheer:
Thanks

Code:
Warning: Spoiler!
Last edit: 3 years 7 months ago by Fu-Bama. Reason: updated code

Please Log in or Create an account to join the conversation.

More
1 year 8 months ago #14 by knowom
Replied by knowom on topic BackBuffer and RenderTarget at one pass?
What would be really cool is if you could interlace individual shader's to reduce the performance overhead as well just to give more granular image impact of the shader themselves. I wouldn't want it on everything, but a interlaced sharpening, AA, and denoise could be handy.

Please Log in or Create an account to join the conversation.