Access to previous frames
- aufkrawall
- Topic Author
once ReShade supports access to previous frames, would it be possible to implement SMAA 2xT in every game?
Would it work even with alternate frame rendering?
Can the same quality be achieved, compared to good solutions like in Ryse or CoD: AW?
I think it won't hurt to make this clear publicly, since the question already has arisen in another forum (3DC).
Thanks!
Please Log in or Create an account to join the conversation.
- crosire
Please Log in or Create an account to join the conversation.
- aufkrawall
- Topic Author
- crosire
It's possible to get access to the last frame by simply copying the current frame to a texture at the end and then using that texture the next time. Something like this:
texture2D currTex : COLOR;
texture2D prevTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
sampler2D currColor { Texture = currTex; };
sampler2D prevColor { Texture = prevTex; };
float4 PS_PostProcess(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
float4 curr = tex2D(currColor, texcoord);
float4 prev = tex2D(prevColor, texcoord);
....
return curr;
}
float4 PS_CopyFrame(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
return tex2D(currColor, texcoord);
}
technique MyTechnique
{
pass DoPostProcessing
{
VertexShader = ...;
PixelShader = PS_PostProcess;
}
pass DoCopyFrameForPrevAccess
{
VertexShader = ...;
PixelShader = PS_CopyFrame;
RenderTarget = prevTex;
}
}
Please Log in or Create an account to join the conversation.
- CeeJay.dk
Please Log in or Create an account to join the conversation.
- crosire
texture2D currTex : COLOR;
texture2D prevTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; };
sampler2D currColor { Texture = currTex; };
sampler2D prevColor { Texture = prevTex; };
void PS_PostProcess(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0, out float4 prevOut : SV_Target1)
{
color = tex2D(currColor, texcoord);
float4 prev = tex2D(prevColor, texcoord);
prevOut = color;
....
}
technique MyTechnique
{
pass
{
VertexShader = ...;
PixelShader = PS_PostProcess;
RenderTarget1 = prevTex;
}
...
}
Please Log in or Create an account to join the conversation.
- Deriest
texture texColor;
texture texPrev1;
texture texPrev2;
texture texPrev3;
...
sampler samplerColor
{
Texture = texColor;
};
sampler samplerPrev01
{
Texture = texPrev01;
};
sampler samplerPrev02
{
Texture = texPrev02;
};
sampler samplerPrev03
{
Texture = texPrev03;
};
...
float4 PS_Main...
float4 PS_Previous03(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target
{
float4 color = tex2D(samplerPrev02, texcoord.xy);
return color;
}
float4 PS_Previous02(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target
{
float4 color = tex2D(samplerPrev01, texcoord.xy);
return color;
}
float4 PS_Previous01(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target
{
float4 color = tex2D(samplerColor, texcoord.xy);
return color;
}
technique MyTechnique
{
passMain
{
VertexShader = ...;
PixelShader = Main;
}
passPrev03
{
VertexShader = ...;
PixelShader = PS_Previous03;
RenderTarget = texPrev03;
}
passPrev02
{
VertexShader = ...;
PixelShader = PS_Previous02;
RenderTarget = texPrev02;
}
passPrev01
{
VertexShader = ...;
PixelShader = PS_Previous01;
RenderTarget = texPrev01;
}
}
Could we sample our previous frame texture to create a previous previous frame? If that makes sense?
Please Log in or Create an account to join the conversation.
- crosire
EDIT: Nevermind. My reading skills failed on me.
Please Log in or Create an account to join the conversation.
- CeeJay.dk
crosire wrote: This copies the current frame again and again. Access to frames older than the previous one needs to be implented in ReShade
Are you sure? .. It seems like this would work as long as the passes are executed in the order he wrote them.
I'd still use a single pass for performance reasons and have that pass output to SV_Target0 , SV_Target1 and SV_Target2
The current frame goes to SV_Target0 and to SV_Target1
and in the beginning of the pass you read from the previous image and then you output that to SV_Target2
Seems like you could make up to the limit of render targets of previous frames this way.
Though I don't think actually you need that if you want to do eye adaptation .. one previous frame should be enough.
Please Log in or Create an account to join the conversation.
- crosire
Please Log in or Create an account to join the conversation.
- Deriest
Please Log in or Create an account to join the conversation.
- crosire
One thing to note here is that there are a few differences between the APIs on how many simultanous rendertargets they allow and that's one of the things ReShade can't change, so to enable full support for all, you should probably go for a maximum of 4 rendertargets (SV_Target0-3), even though ReShade in theory supports up to 8:CeeJay.dk wrote: I'd still use a single pass for performance reasons and have that pass output to SV_Target0 , SV_Target1 and SV_Target2
- Direct3D9: D3DCAPS9.NumSimultaneousRTs = usually at least 4 on modern cards
- Direct3D10/11: D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT = 8
- OpenGL: GL_MAX_DRAW_BUFFERS = usually the same as for Direct3D10/11
Please Log in or Create an account to join the conversation.
- Ganossa
Here is the sample code::
texture2D currTex : COLOR;
texture2D prevTex : SV_TARGET0;
sampler2D currColor
{
Texture = currTex;
AddressU = CLAMP;
AddressV = CLAMP;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
};
sampler2D prevColor
{
Texture = prevTex;
AddressU = CLAMP;
AddressV = CLAMP;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
};
void VS_PostProcess(in uint id : VERTEXID, out float4 pos : POSITION, out float2 texcoord : TEXCOORD)
{
texcoord.x = (id == 2) ? 2.0 : 0.0;
texcoord.y = (id == 1) ? 2.0 : 0.0;
pos = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
}
float4 PS_Prev(float4 vpos : VPOS, float2 texcoord : TEXCOORD) : SV_TARGET0
{
float4 curr = tex2D(currColor, texcoord);
return curr;
}
float4 PS_PrevOut(float4 vpos : VPOS, float2 texcoord : TEXCOORD) : COLOR
{
float4 prev = tex2D(prevColor, texcoord);
return prev;
}
technique SamplePrev < bool enabled = true; >
{
pass Prev
{
VertexShader = VS_PostProcess;
PixelShader = PS_Prev;
RenderTarget = prevTex;
}
pass PrevOut
{
VertexShader = VS_PostProcess;
PixelShader = PS_PrevOut;
}
}
Even when I sample over the current frame and write/render it to another texture, this texture will remain black.
It would also be helpful to get a language extension that allows to copy resources, so I do not need to render the same thing on different textures.
Please Log in or Create an account to join the conversation.
- crosire
To create a texture you can actually write to (the above is read only), you have to define it like this (as an example, "BUFFER_WIDTH" and "BUFFER_HEIGHT" are defines resolving to the backbuffer size), so ReShade knows what to do with it:
texture2D prevTex
{
Width = BUFFER_WIDTH;
Height = BUFFER_HEIGHT;
Format = RGBA8;
}
Please Log in or Create an account to join the conversation.
- Ganossa
Please Log in or Create an account to join the conversation.
- aufkrawall
- Topic Author
This could be useful to mitigate unwanted motion blur effects, like the extreme motion blur that comes with Far Cry 4 temporal SMAA or unwanted motion blur in general, e.g. if can't be turned off.
LuciferHawk, may I ask how you rate the possible effectiveness of temporal SMAA, injected via ReShade? Do you think it can be as good as if it was implemented by the game itself?
Please Log in or Create an account to join the conversation.
- JPulowski
I don't understand. What do you mean by "temporal" lumasharpen? And how could it de-motion blur the image exactly?aufkrawall wrote: This could be useful to mitigate unwanted motion blur effects, like the extreme motion blur that comes with Far Cry 4 temporal SMAA or unwanted motion blur in general, e.g. if can't be turned off.
Theoretically speaking, the answer is yes. Basic SMAA could be also good as native SMAA as well. And actually it is possible to do so currently in few games which support depth-buffer access, by choosing depth edge detection instead of color/luma edge detection. It is not perfect, but still it allows to by-pass the HUD. In the future ReShade will have an automated generic UI detection feature. GeDoSaTO currently has one, you just write the corresponding hash codes of UI textures/elements then it by-passes them, but it is all manual. ReShade will do everything, automatically.aufkrawall wrote: Do you think it can be as good as if it was implemented by the game itself?
Please Log in or Create an account to join the conversation.
- aufkrawall
- Topic Author
I have no idea, that's why I ask.JPulowski wrote: I don't understand. What do you mean by "temporal" lumasharpen? And how could it de-motion blur the image exactly?
Maybe you could do primitive stuff like enhancing contrast of pixels or increase sharpening when motion in many screen areas is detected.
I don't know if it ever could be useful in terms of quality. It will probably never look close to no motion blur.
But who knows what shader gurus would say.
With previous ReShade and SweetFX 2.0 versions, I had no success with depth detection of SMAA, even though depth buffer detection of ReShade was working fine.JPulowski wrote: Theoretically speaking, the answer is yes. Basic SMAA could be also good as native SMAA as well. And actually it is possible to do so currently in few games which support depth-buffer access, by choosing depth edge detection instead of color/luma edge detection. It is not perfect, but still it allows to by-pass the HUD. In the future ReShade will have an automated generic UI detection feature. GeDoSaTO currently has one, you just write the corresponding hash codes of UI textures/elements then it by-passes them, but it is all manual. ReShade will do everything, automatically.
There was simply no AA applied to any pixel. I will give it another try with newer versions as soon as I have my system working again.
Please Log in or Create an account to join the conversation.
- Ganossa
Please Log in or Create an account to join the conversation.
- aufkrawall
- Topic Author