mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Attempts a linear comb filter for YC separation, plus post-separation Y filtering.
This commit is contained in:
parent
cd1e796093
commit
f3174069fa
@ -96,7 +96,9 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) {
|
|||||||
} else {
|
} else {
|
||||||
result +=
|
result +=
|
||||||
"out vec2 textureCoordinates[11];"
|
"out vec2 textureCoordinates[11];"
|
||||||
"uniform sampler2D textureName;";
|
"out vec2 combCoordinates[2];"
|
||||||
|
"uniform sampler2D textureName;"
|
||||||
|
"uniform float combOffset;";
|
||||||
}
|
}
|
||||||
|
|
||||||
result +=
|
result +=
|
||||||
@ -132,6 +134,9 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) {
|
|||||||
"textureCoordinates[9] = sourcePosition + vec2(4.0, 0.0) / textureSize(textureName, 0);"
|
"textureCoordinates[9] = sourcePosition + vec2(4.0, 0.0) / textureSize(textureName, 0);"
|
||||||
"textureCoordinates[10] = sourcePosition + vec2(5.0, 0.0) / textureSize(textureName, 0);"
|
"textureCoordinates[10] = sourcePosition + vec2(5.0, 0.0) / textureSize(textureName, 0);"
|
||||||
|
|
||||||
|
"combCoordinates[0] = sourcePosition - vec2(combOffset, 0.0);"
|
||||||
|
"combCoordinates[1] = sourcePosition + vec2(combOffset, 0.0);"
|
||||||
|
|
||||||
"eyePosition = eyePosition;";
|
"eyePosition = eyePosition;";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,13 +354,13 @@ std::unique_ptr<Shader> ScanTarget::svideo_to_rgb_shader(int colour_cycle_numera
|
|||||||
(Colour cycle numerator)/(Colour cycle denominator) gives the number of colour cycles in (processing_width / LineBufferWidth),
|
(Colour cycle numerator)/(Colour cycle denominator) gives the number of colour cycles in (processing_width / LineBufferWidth),
|
||||||
there'll be at least four samples per colour clock and in practice at most just a shade more than 9.
|
there'll be at least four samples per colour clock and in practice at most just a shade more than 9.
|
||||||
*/
|
*/
|
||||||
auto coefficients = coefficients_for_filter(colour_cycle_numerator, colour_cycle_denominator, processing_width, 0.25f);
|
|
||||||
auto shader = std::unique_ptr<Shader>(new Shader(
|
auto shader = std::unique_ptr<Shader>(new Shader(
|
||||||
glsl_globals(ShaderType::ProcessedScan) + glsl_default_vertex_shader(ShaderType::ProcessedScan),
|
glsl_globals(ShaderType::ProcessedScan) + glsl_default_vertex_shader(ShaderType::ProcessedScan),
|
||||||
"#version 150\n"
|
"#version 150\n"
|
||||||
|
|
||||||
"in vec2 textureCoordinates[11];"
|
"in vec2 textureCoordinates[11];"
|
||||||
"uniform vec4 textureWeights[3];"
|
"uniform vec4 chromaWeights[3];"
|
||||||
|
"uniform vec4 lumaWeights[3];"
|
||||||
"uniform sampler2D textureName;"
|
"uniform sampler2D textureName;"
|
||||||
"uniform mat3 lumaChromaToRGB;"
|
"uniform mat3 lumaChromaToRGB;"
|
||||||
|
|
||||||
@ -374,6 +379,11 @@ std::unique_ptr<Shader> ScanTarget::svideo_to_rgb_shader(int colour_cycle_numera
|
|||||||
"texture(textureName, textureCoordinates[9]).rgb,"
|
"texture(textureName, textureCoordinates[9]).rgb,"
|
||||||
"texture(textureName, textureCoordinates[10]).rgb"
|
"texture(textureName, textureCoordinates[10]).rgb"
|
||||||
");"
|
");"
|
||||||
|
"vec4 samples0[3] = vec4[3]("
|
||||||
|
"vec4(samples[0].r, samples[1].r, samples[2].r, samples[3].r),"
|
||||||
|
"vec4(samples[4].r, samples[5].r, samples[6].r, samples[7].r),"
|
||||||
|
"vec4(samples[8].r, samples[9].r, samples[10].r, 0.0)"
|
||||||
|
");"
|
||||||
"vec4 samples1[3] = vec4[3]("
|
"vec4 samples1[3] = vec4[3]("
|
||||||
"vec4(samples[0].g, samples[1].g, samples[2].g, samples[3].g),"
|
"vec4(samples[0].g, samples[1].g, samples[2].g, samples[3].g),"
|
||||||
"vec4(samples[4].g, samples[5].g, samples[6].g, samples[7].g),"
|
"vec4(samples[4].g, samples[5].g, samples[6].g, samples[7].g),"
|
||||||
@ -384,27 +394,33 @@ std::unique_ptr<Shader> ScanTarget::svideo_to_rgb_shader(int colour_cycle_numera
|
|||||||
"vec4(samples[4].b, samples[5].b, samples[6].b, samples[7].b),"
|
"vec4(samples[4].b, samples[5].b, samples[6].b, samples[7].b),"
|
||||||
"vec4(samples[8].b, samples[9].b, samples[10].b, 0.0)"
|
"vec4(samples[8].b, samples[9].b, samples[10].b, 0.0)"
|
||||||
");"
|
");"
|
||||||
"float channel1 = dot(textureWeights[0], samples1[0]) + dot(textureWeights[1], samples1[1]) + dot(textureWeights[2], samples1[2]);"
|
"float channel0 = dot(lumaWeights[0], samples0[0]) + dot(lumaWeights[1], samples0[1]) + dot(lumaWeights[2], samples0[2]);"
|
||||||
"float channel2 = dot(textureWeights[0], samples2[0]) + dot(textureWeights[1], samples2[1]) + dot(textureWeights[2], samples2[2]);"
|
"float channel1 = dot(chromaWeights[0], samples1[0]) + dot(chromaWeights[1], samples1[1]) + dot(chromaWeights[2], samples1[2]);"
|
||||||
|
"float channel2 = dot(chromaWeights[0], samples2[0]) + dot(chromaWeights[1], samples2[1]) + dot(chromaWeights[2], samples2[2]);"
|
||||||
"vec2 chroma = vec2(channel1, channel2)*2.0 - vec2(1.0);"
|
"vec2 chroma = vec2(channel1, channel2)*2.0 - vec2(1.0);"
|
||||||
"fragColour = lumaChromaToRGB * vec3(samples[5].x, chroma);"
|
"fragColour = lumaChromaToRGB * vec3(channel0, chroma);"
|
||||||
"}",
|
"}",
|
||||||
attribute_bindings(ShaderType::ProcessedScan)
|
attribute_bindings(ShaderType::ProcessedScan)
|
||||||
));
|
));
|
||||||
|
|
||||||
coefficients.push_back(0.0f);
|
auto chroma_coefficients = coefficients_for_filter(colour_cycle_numerator, colour_cycle_denominator, processing_width, 0.25f);
|
||||||
shader->set_uniform("textureWeights", 4, 3, coefficients.data());
|
chroma_coefficients.push_back(0.0f);
|
||||||
|
shader->set_uniform("chromaWeights", 4, 3, chroma_coefficients.data());
|
||||||
|
|
||||||
|
auto luma_coefficients = coefficients_for_filter(colour_cycle_numerator, colour_cycle_denominator, processing_width, 0.5f);
|
||||||
|
luma_coefficients.push_back(0.0f);
|
||||||
|
shader->set_uniform("lumaWeights", 4, 3, luma_coefficients.data());
|
||||||
|
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Shader> ScanTarget::composite_to_svideo_shader(int colour_cycle_numerator, int colour_cycle_denominator, int processing_width) {
|
std::unique_ptr<Shader> ScanTarget::composite_to_svideo_shader(int colour_cycle_numerator, int colour_cycle_denominator, int processing_width) {
|
||||||
auto coefficients = coefficients_for_filter(colour_cycle_numerator, colour_cycle_denominator, processing_width, 0.5f);
|
|
||||||
auto shader = std::unique_ptr<Shader>(new Shader(
|
auto shader = std::unique_ptr<Shader>(new Shader(
|
||||||
glsl_globals(ShaderType::ProcessedScan) + glsl_default_vertex_shader(ShaderType::ProcessedScan),
|
glsl_globals(ShaderType::ProcessedScan) + glsl_default_vertex_shader(ShaderType::ProcessedScan),
|
||||||
"#version 150\n"
|
"#version 150\n"
|
||||||
|
|
||||||
"in vec2 textureCoordinates[11];"
|
"in vec2 textureCoordinates[11];"
|
||||||
|
"in vec2 combCoordinates[2];"
|
||||||
"in float compositeAngle;"
|
"in float compositeAngle;"
|
||||||
"in float oneOverCompositeAmplitude;"
|
"in float oneOverCompositeAmplitude;"
|
||||||
|
|
||||||
@ -413,21 +429,18 @@ std::unique_ptr<Shader> ScanTarget::composite_to_svideo_shader(int colour_cycle_
|
|||||||
|
|
||||||
"out vec3 fragColour;"
|
"out vec3 fragColour;"
|
||||||
"void main() {"
|
"void main() {"
|
||||||
"vec4 samples[3] = vec4[3]("
|
"float luma = mix(texture(textureName, combCoordinates[0]).r, texture(textureName, combCoordinates[1]).r, 0.5);"
|
||||||
"vec4(texture(textureName, textureCoordinates[0]).r, texture(textureName, textureCoordinates[1]).r, texture(textureName, textureCoordinates[2]).r, texture(textureName, textureCoordinates[3]).r),"
|
"float centre = texture(textureName, textureCoordinates[5]).r;"
|
||||||
"vec4(texture(textureName, textureCoordinates[4]).r, texture(textureName, textureCoordinates[5]).r, texture(textureName, textureCoordinates[6]).r, texture(textureName, textureCoordinates[7]).r),"
|
|
||||||
"vec4(texture(textureName, textureCoordinates[8]).r, texture(textureName, textureCoordinates[9]).r, texture(textureName, textureCoordinates[10]).r, 0.0)"
|
|
||||||
");"
|
|
||||||
"float luma = dot(textureWeights[0], samples[0]) + dot(textureWeights[1], samples[1]) + dot(textureWeights[2], samples[2]);"
|
|
||||||
"vec2 quadrature = vec2(cos(compositeAngle), sin(compositeAngle));"
|
"vec2 quadrature = vec2(cos(compositeAngle), sin(compositeAngle));"
|
||||||
"vec2 chroma = ((samples[1].y - luma) * oneOverCompositeAmplitude)*quadrature;"
|
"vec2 chroma = ((centre - luma) * oneOverCompositeAmplitude)*quadrature;"
|
||||||
"fragColour = vec3(luma, chroma*0.5 + vec2(0.5));"
|
"fragColour = vec3(luma, chroma*0.5 + vec2(0.5));"
|
||||||
"}",
|
"}",
|
||||||
attribute_bindings(ShaderType::ProcessedScan)
|
attribute_bindings(ShaderType::ProcessedScan)
|
||||||
));
|
));
|
||||||
|
|
||||||
coefficients.push_back(0.0f);
|
const float cycles_per_expanded_line = (float(colour_cycle_numerator) / float(colour_cycle_denominator)) / (float(processing_width) / float(LineBufferWidth));
|
||||||
shader->set_uniform("textureWeights", 4, 3, coefficients.data());
|
float quarter_distancce = 0.25f / cycles_per_expanded_line;
|
||||||
|
shader->set_uniform("combOffset", quarter_distancce);
|
||||||
|
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user