Skip to content

Commit

Permalink
Core / DolphinQt / VideoCommon - support passive/anaglpyh logic in co…
Browse files Browse the repository at this point in the history
…njunction with any custom post processing shaders
  • Loading branch information
iwubcode committed Jan 8, 2022
1 parent 86227e3 commit 5ce0dc7
Show file tree
Hide file tree
Showing 18 changed files with 286 additions and 22 deletions.
20 changes: 20 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/dubois-LCD-Amber-Blue.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Anaglyph Amber-Blue shader based on Dubois algorithm
// Constants taken from the screenshot:
// "https://www.flickr.com/photos/e_dubois/5230654930/"
// Eric Dubois

void main()
{
float4 c0 = SampleLayer(0);
float4 c1 = SampleLayer(1);

float3 lr = float3( 1.062,-0.205, 0.299);
float3 lg = float3(-0.026, 0.908, 0.068);
float3 lb = float3(-0.038,-0.173, 0.022);

float3 rr = float3(-0.016,-0.123,-0.017);
float3 rg = float3( 0.006, 0.062, 0.017);
float3 rb = float3(-0.094,-0.185, 0.991);

SetOutput(float4(dot(lr, c0.rgb) + dot(rr, c1.rgb), dot(lg, c0.rgb) + dot(rg, c1.rgb), dot(lb, c0.rgb) + dot(rb, c1.rgb), c0.a));
}
20 changes: 20 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/dubois-LCD-Green-Magenta.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Anaglyph Green-Magenta shader based on Dubois algorithm
// Constants taken from the screenshot:
// "https://www.flickr.com/photos/e_dubois/5132528166/"
// Eric Dubois

void main()
{
float4 c0 = SampleLayer(0);
float4 c1 = SampleLayer(1);

float3 lr = float3(-0.062,-0.158,-0.039);
float3 lg = float3( 0.284, 0.668, 0.143);
float3 lb = float3(-0.015,-0.027, 0.021);

float3 rr = float3( 0.529, 0.705, 0.024);
float3 rg = float3(-0.016,-0.015, 0.065);
float3 rb = float3( 0.009, 0.075, 0.937);

SetOutput(float4(dot(lr, c0.rgb) + dot(rr, c1.rgb), dot(lg, c0.rgb) + dot(rg, c1.rgb), dot(lb, c0.rgb) + dot(rb, c1.rgb), c0.a));
}
21 changes: 21 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/dubois.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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

void main()
{
float4 c0 = SampleLayer(0);
float4 c1 = SampleLayer(1);

float3 lr = float3( 0.437, 0.449, 0.164);
float3 lg = float3(-0.062,-0.062,-0.024);
float3 lb = float3(-0.048,-0.050,-0.017);

float3 rr = float3(-0.011,-0.032,-0.007);
float3 rg = float3( 0.377, 0.761, 0.009);
float3 rb = float3(-0.026,-0.093, 1.234);

SetOutput(float4(dot(lr, c0.rgb) + dot(rr, c1.rgb), dot(lg, c0.rgb) + dot(rg, c1.rgb), dot(lb, c0.rgb) + dot(rb, c1.rgb), c0.a));
}
8 changes: 8 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/fullcolor.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Anaglyph Red-Cyan shader without compensation

void main()
{
float4 c0 = SampleLayer(0);
float4 c1 = SampleLayer(1);
SetOutput(float4(c0.r, c1.gb, c0.a));
}
10 changes: 10 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/grayscale.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Anaglyph Red-Cyan grayscale shader

void main()
{
float4 c0 = SampleLayer(0);
float avg0 = (c0.r + c0.g + c0.b) / 3.0;
float4 c1 = SampleLayer(1);
float avg1 = (c1.r + c1.g + c1.b) / 3.0;
SetOutput(float4(avg0, avg1, avg1, c0.a));
}
12 changes: 12 additions & 0 deletions Data/Sys/Shaders/Internal/Anaglyph/grayscale2.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Anaglyph Red-Cyan luma grayscale shader
// Info: https://web.archive.org/web/20040101053504/http://www.oreillynet.com:80/cs/user/view/cs_msg/8691

void main()
{
float3 luma = float3(0.222, 0.707, 0.071);
float4 c0 = SampleLayer(0);
float avg0 = dot(c0.rgb, luma);
float4 c1 = SampleLayer(1);
float avg1 = dot(c1.rgb, luma);
SetOutput(float4(avg0, avg1, avg1, c0.a));
}
7 changes: 7 additions & 0 deletions Data/Sys/Shaders/Internal/Passive/horizontal.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Passive (horizontal rows) shader

void main()
{
float screen_row = GetWindowResolution().y * GetCoordinates().y;
SetOutput(SampleLayer(int(screen_row) % 2));
}
2 changes: 0 additions & 2 deletions Source/Core/Common/CommonPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@
#define THEMES_DIR "Themes"
#define STYLES_DIR "Styles"
#define GBASAVES_DIR "Saves"
#define ANAGLYPH_DIR "Anaglyph"
#define PASSIVE_DIR "Passive"
#define PIPES_DIR "Pipes"
#define MEMORYWATCHER_DIR "MemoryWatcher"
#define WFSROOT_DIR "WFS"
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Config/GraphicsSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ const Info<bool> GFX_STEREO_EFB_MONO_DEPTH{{System::GFX, "Stereoscopy", "StereoE
false};
const Info<int> GFX_STEREO_DEPTH_PERCENTAGE{{System::GFX, "Stereoscopy", "StereoDepthPercentage"},
100};
const Info<std::string> GFX_STEREO_SHADER{{System::GFX, "Stereoscopy", "Shader"},
""};

// Graphics.Hacks

Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/Config/GraphicsSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ extern const Info<bool> GFX_STEREO_SWAP_EYES;
extern const Info<int> GFX_STEREO_CONVERGENCE;
extern const Info<bool> GFX_STEREO_EFB_MONO_DEPTH;
extern const Info<int> GFX_STEREO_DEPTH_PERCENTAGE;
extern const Info<std::string> GFX_STEREO_SHADER;

// Stereoscopy pseudo-limits for consistent behavior between enhancements tab and hotkeys.
static constexpr int GFX_STEREO_DEPTH_MAXIMUM = 100;
Expand Down
112 changes: 106 additions & 6 deletions Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
#include "DolphinQt/Config/Graphics/EnhancementsWidget.h"

#include <cmath>
#include <optional>

#include <QDir>
#include <QFileInfo>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>

#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/ConfigManager.h"

Expand All @@ -24,6 +30,7 @@

#include "UICommon/VideoUtils.h"

#include "VideoCommon/PEShaderSystem/Constants.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h"
Expand Down Expand Up @@ -122,14 +129,17 @@ void EnhancementsWidget::CreateWidgets()
m_3d_convergence = new GraphicsSlider(0, Config::GFX_STEREO_CONVERGENCE_MAXIMUM,
Config::GFX_STEREO_CONVERGENCE, 100);
m_3d_swap_eyes = new GraphicsBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES);
m_3d_shader = new ToolTipComboBox();

stereoscopy_layout->addWidget(new QLabel(tr("Stereoscopic 3D Mode:")), 0, 0);
stereoscopy_layout->addWidget(m_3d_mode, 0, 1);
stereoscopy_layout->addWidget(new QLabel(tr("Depth:")), 1, 0);
stereoscopy_layout->addWidget(m_3d_depth, 1, 1);
stereoscopy_layout->addWidget(new QLabel(tr("Convergence:")), 2, 0);
stereoscopy_layout->addWidget(m_3d_convergence, 2, 1);
stereoscopy_layout->addWidget(m_3d_swap_eyes, 3, 0);
stereoscopy_layout->addWidget(new QLabel(tr("Shader:")), 1, 0);
stereoscopy_layout->addWidget(m_3d_shader, 1, 1);
stereoscopy_layout->addWidget(new QLabel(tr("Depth:")), 2, 0);
stereoscopy_layout->addWidget(m_3d_depth, 2, 1);
stereoscopy_layout->addWidget(new QLabel(tr("Convergence:")), 3, 0);
stereoscopy_layout->addWidget(m_3d_convergence, 3, 1);
stereoscopy_layout->addWidget(m_3d_swap_eyes, 4, 0);

main_layout->addWidget(enhancements_box);
main_layout->addWidget(stereoscopy_box);
Expand All @@ -142,7 +152,14 @@ void EnhancementsWidget::ConnectWidgets()
{
connect(m_aa_combo, qOverload<int>(&QComboBox::currentIndexChanged),
[this](int) { SaveSettings(); });
connect(m_3d_mode, qOverload<int>(&QComboBox::currentIndexChanged), [this] { SaveSettings(); });
connect(m_3d_mode, qOverload<int>(&QComboBox::currentIndexChanged), [this] {
m_block_save = true;
OnStereoModeChanged();
m_block_save = false;

SaveSettings();
});
connect(m_3d_shader, qOverload<int>(&QComboBox::currentIndexChanged), [this] { SaveSettings(); });
connect(m_pp_configure, &QPushButton::pressed, this, [this]() {
if (!m_shader_window)
m_shader_window = new CustomShaderWindow;
Expand Down Expand Up @@ -174,6 +191,14 @@ void EnhancementsWidget::LoadSettings()
m_3d_convergence->setEnabled(supports_stereoscopy);
m_3d_depth->setEnabled(supports_stereoscopy);
m_3d_swap_eyes->setEnabled(supports_stereoscopy);
if (supports_stereoscopy)
{
OnStereoModeChanged();
}
else
{
m_3d_shader->setEnabled(false);
}
m_block_save = false;
}

Expand All @@ -200,6 +225,16 @@ void EnhancementsWidget::SaveSettings()

Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa);

if (m_3d_shader->count() > 0)
{
Config::SetBaseOrCurrent(Config::GFX_STEREO_SHADER,
m_3d_shader->currentData().toString().toStdString());
}
else
{
Config::SetBaseOrCurrent(Config::GFX_STEREO_SHADER, "");
}

LoadSettings();
}

Expand Down Expand Up @@ -323,3 +358,68 @@ void EnhancementsWidget::AddDescriptions()

m_3d_swap_eyes->SetDescription(tr(TR_3D_SWAP_EYES_DESCRIPTION));
}

void EnhancementsWidget::OnStereoModeChanged()
{
m_3d_shader->clear();

const auto stereo_mode = Config::Get<StereoMode>(Config::GFX_STEREO_MODE);
if (stereo_mode == StereoMode::Anaglyph || stereo_mode == StereoMode::Passive)
{
const auto current_stereo_shader = Config::Get(Config::GFX_STEREO_SHADER);
m_3d_shader->setEnabled(true);
std::string std_shader_path;
std::string default_shader_path;
std::string sys_dir = File::GetSysDirectory();
sys_dir = ReplaceAll(std::move(sys_dir), "\\", DIR_SEP);
if (stereo_mode == StereoMode::Anaglyph)
{
std_shader_path = fmt::format(
"{}{}/{}", sys_dir,
VideoCommon::PE::Constants::dolphin_shipped_internal_shader_directory, "Anaglyph");
default_shader_path = fmt::format("{}/{}", std_shader_path, "dubois.glsl");
}
else
{
std_shader_path = fmt::format(
"{}{}/{}", sys_dir,
VideoCommon::PE::Constants::dolphin_shipped_internal_shader_directory, "Passive");
default_shader_path = fmt::format("{}/{}", std_shader_path, "horizontal.glsl");
}

std::optional<int> selected_index;
int default_index = 0;
int index = 0;
const QDir shader_path(QString::fromStdString(std_shader_path));
for (QFileInfo info : shader_path.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot))
{
if (info.isFile())
{
const std::string path = info.absoluteFilePath().toStdString();
m_3d_shader->addItem(info.baseName(), info.absoluteFilePath());
if (path == current_stereo_shader)
{
selected_index = index;
}
if (path == default_shader_path)
{
default_index = index;
}
index++;
}
}

if (selected_index)
{
m_3d_shader->setCurrentIndex(*selected_index);
}
else
{
m_3d_shader->setCurrentIndex(default_index);
}
}
else
{
m_3d_shader->setEnabled(false);
}
}
3 changes: 3 additions & 0 deletions Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class EnhancementsWidget final : public GraphicsWidget
void ConnectWidgets();
void AddDescriptions();

void OnStereoModeChanged();

// Enhancements
GraphicsChoice* m_ir_combo;
ToolTipComboBox* m_aa_combo;
Expand All @@ -52,6 +54,7 @@ class EnhancementsWidget final : public GraphicsWidget
GraphicsSlider* m_3d_depth;
GraphicsSlider* m_3d_convergence;
GraphicsBool* m_3d_swap_eyes;
ToolTipComboBox* m_3d_shader;

int m_msaa_modes;
bool m_block_save;
Expand Down
18 changes: 11 additions & 7 deletions Source/Core/DolphinQt/HotkeyScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <cmath>
#include <thread>

#include <fmt/format.h>

#include <QApplication>
#include <QCoreApplication>

Expand Down Expand Up @@ -44,7 +46,7 @@
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoConfig.h"

constexpr const char* DUBOIS_ALGORITHM_SHADER = "dubois";
#include "VideoCommon/PEShaderSystem/Constants.h"

HotkeyScheduler::HotkeyScheduler() : m_stop_requested(false)
{
Expand Down Expand Up @@ -489,14 +491,17 @@ void HotkeyScheduler::Run()
if (IsHotkey(HK_LOAD_STATE_SLOT_SELECTED))
emit StateLoadSlotHotkey();

const std::string dubois_algorithm_shader = fmt::format(
"{}/{}/{}", File::GetSysDirectory(),
VideoCommon::PE::Constants::dolphin_shipped_internal_shader_directory, "Anaglyph/dubois.glsl");

// Stereoscopy
if (IsHotkey(HK_TOGGLE_STEREO_SBS))
{
if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::SBS)
{
// Disable post-processing shader, as stereoscopy itself is currently a shader
if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) == DUBOIS_ALGORITHM_SHADER)
Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
Config::SetCurrent(Config::GFX_STEREO_SHADER, "");

Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::SBS);
}
Expand All @@ -511,8 +516,7 @@ void HotkeyScheduler::Run()
if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::TAB)
{
// Disable post-processing shader, as stereoscopy itself is currently a shader
if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) == DUBOIS_ALGORITHM_SHADER)
Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
Config::SetCurrent(Config::GFX_STEREO_SHADER, "");

Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::TAB);
}
Expand All @@ -527,12 +531,12 @@ void HotkeyScheduler::Run()
if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::Anaglyph)
{
Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Anaglyph);
Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, DUBOIS_ALGORITHM_SHADER);
Config::SetCurrent(Config::GFX_STEREO_SHADER, dubois_algorithm_shader);
}
else
{
Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Off);
Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
Config::SetCurrent(Config::GFX_STEREO_SHADER, "");
}
}

Expand Down
1 change: 0 additions & 1 deletion Source/Core/UICommon/UICommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ void CreateDirectories()
File::CreateFullPath(File::GetUserPath(D_MAPS_IDX));
File::CreateFullPath(File::GetUserPath(D_SCREENSHOTS_IDX));
File::CreateFullPath(File::GetUserPath(D_SHADERS_IDX));
File::CreateFullPath(File::GetUserPath(D_SHADERS_IDX) + ANAGLYPH_DIR DIR_SEP);
File::CreateFullPath(File::GetUserPath(D_STATESAVES_IDX));
#ifndef ANDROID
File::CreateFullPath(File::GetUserPath(D_THEMES_IDX));
Expand Down
Loading

0 comments on commit 5ce0dc7

Please sign in to comment.