Proper depth buffer handling in Citra
- HenrikoMagnifico
- Topic Author
Less
More
5 years 3 months ago #1
by HenrikoMagnifico
Proper depth buffer handling in Citra was created by HenrikoMagnifico
Hi!
I'm a huge fan of ReShade and would love to be able to use it inside the Citra Nintendo 3DS emulator. At the moment, the depth buffer information sent out by Citra is flipped 90° so most of the ReShade effects don't work properly or at all. Multiple users have contacted the Citra developers but they refuse to implement an option to flip the depth buffer since it's against their moto of "making the emulator as accurate as possible to original hardware". Instead, I put my faith in the developers of ReShade here on ReShade forums. All that's needed would be a toggle in the ReShade menu to "Rotate depth buffer 90°". This feature would really make my day because 3DS games look great in Citra with upscaling but most games really miss some kind of AO or other graphical effects to make them truly enjoyable on the big screen.
Thanks in advance!
Cheers,
Henriko
I'm a huge fan of ReShade and would love to be able to use it inside the Citra Nintendo 3DS emulator. At the moment, the depth buffer information sent out by Citra is flipped 90° so most of the ReShade effects don't work properly or at all. Multiple users have contacted the Citra developers but they refuse to implement an option to flip the depth buffer since it's against their moto of "making the emulator as accurate as possible to original hardware". Instead, I put my faith in the developers of ReShade here on ReShade forums. All that's needed would be a toggle in the ReShade menu to "Rotate depth buffer 90°". This feature would really make my day because 3DS games look great in Citra with upscaling but most games really miss some kind of AO or other graphical effects to make them truly enjoyable on the big screen.
Thanks in advance!
Cheers,
Henriko
Please Log in or Create an account to join the conversation.
5 years 3 months ago - 5 years 3 months ago #2
by Fu-Bama
Replied by Fu-Bama on topic Proper depth buffer handling in Citra
You can add following to the ReShade.fxh, after the preprocessor definitions:and this inside the GetLinearizedDepth function, at the beginning:
...or just grab the whole file:
After that, define new preprocessor definition in Reshade UI
RESHADE_DEPTH_INPUT_IS_CITRA 1
#ifndef RESHADE_DEPTH_INPUT_IS_CITRA
#define RESHADE_DEPTH_INPUT_IS_CITRA 0
#endif
#if RESHADE_DEPTH_INPUT_IS_CITRA
float citra_x = texcoord.x;
texcoord.x = texcoord.y;
texcoord.y = citra_x;
#endif
...or just grab the whole file:
Warning: Spoiler!
#pragma once
#if !defined(__RESHADE__) || __RESHADE__ < 30000
#error "ReShade 3.0+ is required to use this header file"
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
#define RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 0
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_REVERSED
#define RESHADE_DEPTH_INPUT_IS_REVERSED 1
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_LOGARITHMIC
#define RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 0
#endif
#ifndef RESHADE_DEPTH_LINEARIZATION_FAR_PLANE
#define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_CITRA
#define RESHADE_DEPTH_INPUT_IS_CITRA 0
#endif
namespace ReShade
{
// Global variables
#if defined(__RESHADE_FXC__)
float GetAspectRatio() { return BUFFER_WIDTH * BUFFER_RCP_HEIGHT; }
float2 GetPixelSize() { return float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); }
float2 GetScreenSize() { return float2(BUFFER_WIDTH, BUFFER_HEIGHT); }
#define AspectRatio GetAspectRatio()
#define PixelSize GetPixelSize()
#define ScreenSize GetScreenSize()
#else
static const float AspectRatio = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
static const float2 PixelSize = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
static const float2 ScreenSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT);
#endif
// Global textures and samplers
texture BackBufferTex : COLOR;
texture DepthBufferTex : DEPTH;
sampler BackBuffer { Texture = BackBufferTex; };
sampler DepthBuffer { Texture = DepthBufferTex; };
// Helper functions
float GetLinearizedDepth(float2 texcoord)
{
#if RESHADE_DEPTH_INPUT_IS_CITRA
float citra_x = texcoord.x;
texcoord.x = texcoord.y;
texcoord.y = citra_x;
#endif
#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
texcoord.y = 1.0 - texcoord.y;
#endif
float depth = tex2Dlod(DepthBuffer, float4(texcoord, 0, 0)).x;
#if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC
const float C = 0.01;
depth = (exp(depth * log(C + 1.0)) - 1.0) / C;
#endif
#if RESHADE_DEPTH_INPUT_IS_REVERSED
depth = 1.0 - depth;
#endif
const float N = 1.0;
depth /= RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - depth * (RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - N);
return depth;
}
}
// Vertex shader generating a triangle covering the entire screen
void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD)
{
texcoord.x = (id == 2) ? 2.0 : 0.0;
texcoord.y = (id == 1) ? 2.0 : 0.0;
position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
}
After that, define new preprocessor definition in Reshade UI
RESHADE_DEPTH_INPUT_IS_CITRA 1
Last edit: 5 years 3 months ago by Fu-Bama.
The following user(s) said Thank You: goCHIEFgo
Please Log in or Create an account to join the conversation.
- HenrikoMagnifico
- Topic Author
Less
More
5 years 3 months ago #3
by HenrikoMagnifico
Replied by HenrikoMagnifico on topic Proper depth buffer handling in Citra
You're a life saver! I'll try this out ASAP
Please Log in or Create an account to join the conversation.
- goCHIEFgo
Less
More
5 years 2 months ago #4
by goCHIEFgo
Replied by goCHIEFgo on topic Proper depth buffer handling in Citra
It sort of worked. But it flipped the wrong direction, from 90° to 180°. And while I can see that change in Displaydepth using global preprocessor definitions, the shaders are stil at the 90° angle. MXAO gives 180° while Quint_MXAO gives me the usual 90°.
Please Log in or Create an account to join the conversation.
- goCHIEFgo
Less
More
5 years 2 months ago #5
by goCHIEFgo
Replied by goCHIEFgo on topic Proper depth buffer handling in Citra
So I finally realized I also had to apply this into qUINT_common if I, or anyone else, wants to use this for RTGI or any of Marty's shaders. I also worked out how to get them the right side up, with the following in qUINT_common:
#if RESHADE_DEPTH_INPUT_IS_CITRA
float citra_x = uv.x;
uv.x = uv.y;
uv.y = citra_x;
#endif
#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
uv.x = 1.0 - uv.x;
The shader is still misaligned:
Player character in shader (and the rest) is also stretched by window, and I can make her really small and wide or tall and slim by resizing window:
Here's RTGI's lighting channel for clearer view of how it's misaligned.
Feels like I'm pretty close, but I don't know what more I can do here.
From my very limited understanding, qUINT takes depth position from a different source than the rest (?), where Reshade.fhx has "texcoord.y" qUINT has "uv.y".
Once I apply DEPTH_INPUT_IS_CITRA the shaders are aligned in the right direction, no rotating needed, but is misaligned, shifted to the left, and stretches to the window size.
The "regular" method without applying the above seems to properly size the player character and by that the shader, no stretching by window size, but is also misaligned; shifted to left, as well as turned at a 90° angle. Problem with that is I don't know how to rotate that, only seems you can flip it horizontally or vertically. Maybe someone who actually knows code can rotate it.
#if RESHADE_DEPTH_INPUT_IS_CITRA
float citra_x = uv.x;
uv.x = uv.y;
uv.y = citra_x;
#endif
#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
uv.x = 1.0 - uv.x;
The shader is still misaligned:
Player character in shader (and the rest) is also stretched by window, and I can make her really small and wide or tall and slim by resizing window:
Here's RTGI's lighting channel for clearer view of how it's misaligned.
Feels like I'm pretty close, but I don't know what more I can do here.
From my very limited understanding, qUINT takes depth position from a different source than the rest (?), where Reshade.fhx has "texcoord.y" qUINT has "uv.y".
Once I apply DEPTH_INPUT_IS_CITRA the shaders are aligned in the right direction, no rotating needed, but is misaligned, shifted to the left, and stretches to the window size.
The "regular" method without applying the above seems to properly size the player character and by that the shader, no stretching by window size, but is also misaligned; shifted to left, as well as turned at a 90° angle. Problem with that is I don't know how to rotate that, only seems you can flip it horizontally or vertically. Maybe someone who actually knows code can rotate it.
Please Log in or Create an account to join the conversation.
- Giodude
Less
More
4 years 5 months ago #6
by Giodude
Replied by Giodude on topic Proper depth buffer handling in Citra
Any update on this? Hoping to do the same
Please Log in or Create an account to join the conversation.