From d167b0913186b8a53962a6784b383cbd44775dac Mon Sep 17 00:00:00 2001 From: Andres Hernandez Date: Thu, 25 Jul 2024 23:39:14 +0200 Subject: [PATCH] Switched Anaglyph shader technique from Dubois to Rendepth (newer method optimized for LCD screens). --- src/android/app/src/main/jni/config.cpp | 2 +- .../configuration/configure_enhancements.cpp | 2 +- src/common/settings.h | 3 +- .../host_shaders/opengl_present_anaglyph.frag | 39 +++++++++++++------ .../host_shaders/vulkan_present_anaglyph.frag | 39 +++++++++++++------ .../renderer_opengl/renderer_opengl.cpp | 2 +- .../renderer_vulkan/renderer_vulkan.cpp | 1 + 7 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 105712aba8..7893e2931f 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -161,7 +161,7 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.factor_3d); std::string default_shader = "none (builtin)"; if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph) - default_shader = "dubois (builtin)"; + default_shader = "rendepth (builtin)"; else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced) default_shader = "horizontal (builtin)"; Settings::values.pp_shader_name = diff --git a/src/citra_qt/configuration/configure_enhancements.cpp b/src/citra_qt/configuration/configure_enhancements.cpp index e1a831eee9..75a2a85316 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -110,7 +110,7 @@ void ConfigureEnhancements::updateShaders(Settings::StereoRenderOption stereo_op std::string current_shader; if (stereo_option == Settings::StereoRenderOption::Anaglyph) { - ui->shader_combobox->addItem(QStringLiteral("dubois (builtin)")); + ui->shader_combobox->addItem(QStringLiteral("rendepth (builtin)")); current_shader = Settings::values.anaglyph_shader_name.GetValue(); } else { ui->shader_combobox->addItem(QStringLiteral("none (builtin)")); diff --git a/src/common/settings.h b/src/common/settings.h index ba556c8c6f..b097166ae8 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -514,7 +514,8 @@ struct Values { SwitchableSetting filter_mode{true, "filter_mode"}; SwitchableSetting pp_shader_name{"none (builtin)", "pp_shader_name"}; - SwitchableSetting anaglyph_shader_name{"dubois (builtin)", "anaglyph_shader_name"}; + SwitchableSetting anaglyph_shader_name{"rendepth (builtin)", + "anaglyph_shader_name"}; SwitchableSetting dump_textures{false, "dump_textures"}; SwitchableSetting custom_textures{false, "custom_textures"}; diff --git a/src/video_core/host_shaders/opengl_present_anaglyph.frag b/src/video_core/host_shaders/opengl_present_anaglyph.frag index c477c437d9..fd2a7ccdcf 100644 --- a/src/video_core/host_shaders/opengl_present_anaglyph.frag +++ b/src/video_core/host_shaders/opengl_present_anaglyph.frag @@ -4,17 +4,22 @@ //? #version 430 core -// Anaglyph Red-Cyan shader based on Dubois algorithm -// Constants taken from the paper: -// "Conversion of a Stereo Pair to Anaglyph with -// the Least-Squares Projection Method" -// Eric Dubois, March 2009 -const mat3 l = mat3( 0.437, 0.449, 0.164, - -0.062,-0.062,-0.024, - -0.048,-0.050,-0.017); -const mat3 r = mat3(-0.011,-0.032,-0.007, - 0.377, 0.761, 0.009, - -0.026,-0.093, 1.234); +// Rendepth: Red/Cyan Anaglyph Filter Optimized for Stereoscopic 3D on LCD Monitors by Andres Hernandez. +// Based on the paper "Producing Anaglyphs from Synthetic Images" by William Sanders, David F. McAllister. +// Using concepts from "Methods for computing color anaglyphs" by David F. McAllister, Ya Zhou, Sophia Sullivan. +// Original research from "Conversion of a Stereo Pair to Anaglyph with the Least-Squares Projection Method" by Eric Dubois + +const mat3 l = mat3( + vec3(0.4561, 0.500484, 0.176381), + vec3(-0.400822, -0.0378246, -0.0157589), + vec3(-0.0152161, -0.0205971, -0.00546856)); + +const mat3 r = mat3( + vec3(-0.0434706, -0.0879388, -0.00155529), + vec3(0.378476, 0.73364, -0.0184503), + vec3(-0.0721527, -0.112961, 1.2264)); + +const vec3 g = vec3(1.6, 0.8, 1.0); layout(location = 0) in vec2 frag_tex_coord; layout(location = 0) out vec4 color; @@ -25,8 +30,18 @@ layout(binding = 1) uniform sampler2D color_texture_r; uniform vec4 resolution; uniform int layer; +vec3 correct_color(vec3 col) { + vec3 result; + result.r = pow(col.r, 1.0 / g.r); + result.g = pow(col.g, 1.0 / g.g); + result.b = pow(col.b, 1.0 / g.b); + return result; +} + void main() { vec4 color_tex_l = texture(color_texture, frag_tex_coord); vec4 color_tex_r = texture(color_texture_r, frag_tex_coord); - color = vec4(color_tex_l.rgb*l+color_tex_r.rgb*r, color_tex_l.a); + vec3 color_anaglyph = clamp(color_tex_l.rgb * l, vec3(0.0), vec3(1.0)) + clamp(color_tex_r.rgb * r, vec3(0.0), vec3(1.0)); + vec3 color_corrected = correct_color(color_anaglyph); + color = vec4(color_corrected, color_tex_l.a); } diff --git a/src/video_core/host_shaders/vulkan_present_anaglyph.frag b/src/video_core/host_shaders/vulkan_present_anaglyph.frag index a01ce63f63..4bfadf3927 100644 --- a/src/video_core/host_shaders/vulkan_present_anaglyph.frag +++ b/src/video_core/host_shaders/vulkan_present_anaglyph.frag @@ -8,17 +8,22 @@ layout (location = 0) in vec2 frag_tex_coord; layout (location = 0) out vec4 color; -// Anaglyph Red-Cyan shader based on Dubois algorithm -// Constants taken from the paper: -// "Conversion of a Stereo Pair to Anaglyph with -// the Least-Squares Projection Method" -// Eric Dubois, March 2009 -const mat3 l = mat3( 0.437, 0.449, 0.164, - -0.062,-0.062,-0.024, - -0.048,-0.050,-0.017); -const mat3 r = mat3(-0.011,-0.032,-0.007, - 0.377, 0.761, 0.009, - -0.026,-0.093, 1.234); +// Rendepth: Red/Cyan Anaglyph Filter Optimized for Stereoscopic 3D on LCD Monitors by Andres Hernandez. +// Based on the paper "Producing Anaglyphs from Synthetic Images" by William Sanders, David F. McAllister. +// Using concepts from "Methods for computing color anaglyphs" by David F. McAllister, Ya Zhou, Sophia Sullivan. +// Original research from "Conversion of a Stereo Pair to Anaglyph with the Least-Squares Projection Method" by Eric Dubois + +const mat3 l = mat3( + vec3(0.4561, 0.500484, 0.176381), + vec3(-0.400822, -0.0378246, -0.0157589), + vec3(-0.0152161, -0.0205971, -0.00546856)); + +const mat3 r = mat3( + vec3(-0.0434706, -0.0879388, -0.00155529), + vec3(0.378476, 0.73364, -0.0184503), + vec3(-0.0721527, -0.112961, 1.2264)); + +const vec3 g = vec3(1.6, 0.8, 1.0); layout (push_constant, std140) uniform DrawInfo { mat4 modelview_matrix; @@ -47,8 +52,18 @@ vec4 GetScreen(int screen_id) { #endif } +vec3 correct_color(vec3 col) { + vec3 result; + result.r = pow(col.r, 1.0 / g.r); + result.g = pow(col.g, 1.0 / g.g); + result.b = pow(col.b, 1.0 / g.b); + return result; +} + void main() { vec4 color_tex_l = GetScreen(screen_id_l); vec4 color_tex_r = GetScreen(screen_id_r); - color = vec4(color_tex_l.rgb*l+color_tex_r.rgb*r, color_tex_l.a); + vec3 color_anaglyph = clamp(color_tex_l.rgb * l, vec3(0.0), vec3(1.0)) + clamp(color_tex_r.rgb * r, vec3(0.0), vec3(1.0)); + vec3 color_corrected = correct_color(color_anaglyph); + color = vec4(color_corrected, color_tex_l.a); } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index ce6cf5386b..a7db24c7aa 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -370,7 +370,7 @@ void RendererOpenGL::ReloadShader() { // Link shaders and get variable locations std::string shader_data = fragment_shader_precision_OES; if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph) { - if (Settings::values.anaglyph_shader_name.GetValue() == "dubois (builtin)") { + if (Settings::values.anaglyph_shader_name.GetValue() == "rendepth (builtin)") { shader_data += HostShaders::OPENGL_PRESENT_ANAGLYPH_FRAG; } else { std::string shader_text = OpenGL::GetPostProcessingShaderCode( diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index f009660856..b764da8c21 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -65,6 +65,7 @@ RendererVulkan::RendererVulkan(Core::System& system, Pica::PicaCore& pica_, CompileShaders(); BuildLayouts(); BuildPipelines(); + ReloadPipeline(); if (secondary_window) { second_window = std::make_unique(*secondary_window, instance, scheduler); }