From e3969f763e62ff5c8a83b2996672b321ed9174ea Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 2 Jan 2015 02:58:52 +0100 Subject: [PATCH 1/4] PostProcessing: Use Dubois algorithm for anaglyph shader. --- .../Core/VideoBackends/OGL/PostProcessing.cpp | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.cpp b/Source/Core/VideoBackends/OGL/PostProcessing.cpp index 74fd93147b..cbcd1b0e9c 100644 --- a/Source/Core/VideoBackends/OGL/PostProcessing.cpp +++ b/Source/Core/VideoBackends/OGL/PostProcessing.cpp @@ -36,6 +36,28 @@ static char s_vertex_shader[] = " uv0 = rawpos * src_rect.zw + src_rect.xy;\n" "}\n"; +// 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 +static char s_anaglyph_shader[] = + "void main() {\n" + " vec3 l = SampleLayer(0).rgb;\n" + " vec3 r = SampleLayer(1).rgb;\n" + " vec3 lr = vec3(0.437,0.449,0.164);\n" + " vec3 lg = vec3(-0.062,-0.062,-0.024);\n" + " vec3 lb = vec3(-0.048,-0.050,-0.017);\n" + " vec3 rr = vec3(-0.011,-0.032,-0.007);\n" + " vec3 rg = vec3(0.377,0.761,0.009);\n" + " vec3 rb = vec3(-0.026,-0.093,1.234);\n" + " vec3 c0 = vec3(dot(l, lr), dot(l, lg), dot(l, lb));\n" + " vec3 c1 = vec3(dot(r, rr), dot(r, rg), dot(r, rb));\n" + " SetOutput(vec4(c0 + c1, SampleLayer(0).a));\n" + "}\n"; + +static const char s_default_shader[] = "void main() { SetOutput(Sample()); }\n"; + OpenGLPostProcessing::OpenGLPostProcessing() : m_initialized(false) , m_anaglyph(false) @@ -172,15 +194,13 @@ void OpenGLPostProcessing::ApplyShader() // load shader code std::string code = ""; - std::string default_shader = "void main() { SetOutput(Sample()); }\n"; - if (g_ActiveConfig.iStereoMode == STEREO_ANAGLYPH) - code = "void main() { SetOutput(float4(pow(0.7 * SampleLayer(0).g + 0.3 * SampleLayer(0).b, 1.5), SampleLayer(1).gba)); }\n"; + code = s_anaglyph_shader; else if (g_ActiveConfig.sPostProcessingShader != "") code = m_config.LoadShader(); if (code == "") - code = default_shader; + code = s_default_shader; code = LoadShaderOptions(code); @@ -194,7 +214,7 @@ void OpenGLPostProcessing::ApplyShader() { ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str()); - code = LoadShaderOptions(default_shader); + code = LoadShaderOptions(s_default_shader); ProgramShaderCache::CompileShader(m_shader, vertex_shader, code.c_str()); } From 491de39325be1488d6ee4800ac7c4051a6b4ebd8 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 2 Jan 2015 03:02:33 +0100 Subject: [PATCH 2/4] PixelShaderCache: Implement Dubois algorithm in anaglyph shader. --- .../VideoBackends/D3D/PixelShaderCache.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index a3e10a2870..adafe5e708 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -61,6 +61,11 @@ const char color_copy_program_code[] = { "}\n" }; +// 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 char anaglyph_program_code[] = { "sampler samp0 : register(s0);\n" "Texture2DArray Tex0 : register(t0);\n" @@ -68,9 +73,17 @@ const char anaglyph_program_code[] = { "out float4 ocol0 : SV_Target,\n" "in float4 pos : SV_Position,\n" "in float3 uv0 : TEXCOORD0){\n" - "float4 c0 = Tex0.Sample(samp0, float3(uv0.xy, 0.0));\n" - "float4 c1 = Tex0.Sample(samp0, float3(uv0.xy, 1.0));\n" - "ocol0 = float4(pow(0.7 * c0.g + 0.3 * c0.b, 1.5), c1.gba);" + "float3 l = Tex0.Sample(samp0, float3(uv0.xy, 0.0)).rgb;\n" + "float3 r = Tex0.Sample(samp0, float3(uv0.xy, 1.0)).rgb;\n" + "float3 lr = float3(0.437,0.449,0.164);\n" + "float3 lg = float3(-0.062,-0.062,-0.024);\n" + "float3 lb = float3(-0.048,-0.050,-0.017);\n" + "float3 rr = float3(-0.011,-0.032,-0.007);\n" + "float3 rg = float3(0.377,0.761,0.009);\n" + "float3 rb = float3(-0.026,-0.093,1.234);\n" + "float3 c0 = float3(dot(l, lr), dot(l, lg), dot(l, lb));\n" + "float3 c1 = float3(dot(r, rr), dot(r, rg), dot(r, rb));\n" + "ocol0 = float4(c0 + c1, 1.0);\n" "}\n" }; From 26a9afa0e7f3f1d8443062c0149cf461412f4ecb Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 2 Jan 2015 13:35:53 +0100 Subject: [PATCH 3/4] Anaglyph: Use matrices instead of vectors. --- .../VideoBackends/D3D/PixelShaderCache.cpp | 20 +++++++++---------- .../Core/VideoBackends/OGL/PostProcessing.cpp | 20 +++++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index adafe5e708..045de131a1 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -73,17 +73,15 @@ const char anaglyph_program_code[] = { "out float4 ocol0 : SV_Target,\n" "in float4 pos : SV_Position,\n" "in float3 uv0 : TEXCOORD0){\n" - "float3 l = Tex0.Sample(samp0, float3(uv0.xy, 0.0)).rgb;\n" - "float3 r = Tex0.Sample(samp0, float3(uv0.xy, 1.0)).rgb;\n" - "float3 lr = float3(0.437,0.449,0.164);\n" - "float3 lg = float3(-0.062,-0.062,-0.024);\n" - "float3 lb = float3(-0.048,-0.050,-0.017);\n" - "float3 rr = float3(-0.011,-0.032,-0.007);\n" - "float3 rg = float3(0.377,0.761,0.009);\n" - "float3 rb = float3(-0.026,-0.093,1.234);\n" - "float3 c0 = float3(dot(l, lr), dot(l, lg), dot(l, lb));\n" - "float3 c1 = float3(dot(r, rr), dot(r, rg), dot(r, rb));\n" - "ocol0 = float4(c0 + c1, 1.0);\n" + "float4 c0 = Tex0.Sample(samp0, float3(uv0.xy, 0.0));\n" + "float4 c1 = Tex0.Sample(samp0, float3(uv0.xy, 1.0));\n" + "float3x3 l = float3x3( 0.437, 0.449, 0.164,\n" + " -0.062,-0.062,-0.024,\n" + " -0.048,-0.050,-0.017);\n" + "float3x3 r = float3x3(-0.011,-0.032,-0.007,\n" + " 0.377, 0.761, 0.009,\n" + " -0.026,-0.093, 1.234);\n" + "ocol0 = float4(mul(l, c0.rgb) + mul(r, c1.rgb), c0.a);\n" "}\n" }; diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.cpp b/Source/Core/VideoBackends/OGL/PostProcessing.cpp index cbcd1b0e9c..16a50cf2de 100644 --- a/Source/Core/VideoBackends/OGL/PostProcessing.cpp +++ b/Source/Core/VideoBackends/OGL/PostProcessing.cpp @@ -43,17 +43,15 @@ static char s_vertex_shader[] = // Eric Dubois, March 2009 static char s_anaglyph_shader[] = "void main() {\n" - " vec3 l = SampleLayer(0).rgb;\n" - " vec3 r = SampleLayer(1).rgb;\n" - " vec3 lr = vec3(0.437,0.449,0.164);\n" - " vec3 lg = vec3(-0.062,-0.062,-0.024);\n" - " vec3 lb = vec3(-0.048,-0.050,-0.017);\n" - " vec3 rr = vec3(-0.011,-0.032,-0.007);\n" - " vec3 rg = vec3(0.377,0.761,0.009);\n" - " vec3 rb = vec3(-0.026,-0.093,1.234);\n" - " vec3 c0 = vec3(dot(l, lr), dot(l, lg), dot(l, lb));\n" - " vec3 c1 = vec3(dot(r, rr), dot(r, rg), dot(r, rb));\n" - " SetOutput(vec4(c0 + c1, SampleLayer(0).a));\n" + " vec4 c0 = SampleLayer(0);\n" + " vec4 c1 = SampleLayer(1);\n" + " mat3 l = mat3( 0.437, 0.449, 0.164,\n" + " -0.062,-0.062,-0.024,\n" + " -0.048,-0.050,-0.017);\n" + " mat3 r = mat3(-0.011,-0.032,-0.007,\n" + " 0.377, 0.761, 0.009,\n" + " -0.026,-0.093, 1.234);\n" + " SetOutput(vec4(c0.rgb * l + c1.rgb * r, c0.a));\n" "}\n"; static const char s_default_shader[] = "void main() { SetOutput(Sample()); }\n"; From 582a15deb38a0510eded144be843f737ed51cca8 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 2 Jan 2015 20:03:20 +0100 Subject: [PATCH 4/4] PostProcessing: Mark all shaders constant. --- Source/Core/VideoBackends/OGL/PostProcessing.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.cpp b/Source/Core/VideoBackends/OGL/PostProcessing.cpp index 16a50cf2de..3c1bb386bf 100644 --- a/Source/Core/VideoBackends/OGL/PostProcessing.cpp +++ b/Source/Core/VideoBackends/OGL/PostProcessing.cpp @@ -18,7 +18,7 @@ namespace OGL { -static char s_vertex_workaround_shader[] = +static const char s_vertex_workaround_shader[] = "in vec4 rawpos;\n" "out vec2 uv0;\n" "uniform vec4 src_rect;\n" @@ -27,7 +27,7 @@ static char s_vertex_workaround_shader[] = " uv0 = rawpos.zw * src_rect.zw + src_rect.xy;\n" "}\n"; -static char s_vertex_shader[] = +static const char s_vertex_shader[] = "out vec2 uv0;\n" "uniform vec4 src_rect;\n" "void main(void) {\n" @@ -41,7 +41,7 @@ static char s_vertex_shader[] = // "Conversion of a Stereo Pair to Anaglyph with // the Least-Squares Projection Method" // Eric Dubois, March 2009 -static char s_anaglyph_shader[] = +static const char s_anaglyph_shader[] = "void main() {\n" " vec4 c0 = SampleLayer(0);\n" " vec4 c1 = SampleLayer(1);\n"