1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Definitively eliminated the additional y filtering step; if I'm going to work to ensure always four samples per colour cycle, I can put the channel separation coefficients directly into their shaders, cutting down on samples.

This commit is contained in:
Thomas Harte 2017-01-07 16:02:33 -05:00
parent 5740015f56
commit 0487b8c178
4 changed files with 68 additions and 107 deletions

View File

@ -18,10 +18,9 @@ using namespace Outputs::CRT;
namespace {
static const GLenum composite_texture_unit = GL_TEXTURE0;
static const GLenum separated_texture_unit = GL_TEXTURE1;
static const GLenum filtered_y_texture_unit = GL_TEXTURE2;
static const GLenum filtered_texture_unit = GL_TEXTURE3;
static const GLenum source_data_texture_unit = GL_TEXTURE4;
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE5;
static const GLenum filtered_texture_unit = GL_TEXTURE2;
static const GLenum source_data_texture_unit = GL_TEXTURE3;
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE4;
}
OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
@ -36,7 +35,6 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
array_builder(SourceVertexBufferDataSize, OutputVertexBufferDataSize),
composite_texture_(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit),
separated_texture_(IntermediateBufferWidth, IntermediateBufferHeight, separated_texture_unit),
filtered_y_texture_(IntermediateBufferWidth, IntermediateBufferHeight, filtered_y_texture_unit),
filtered_texture_(IntermediateBufferWidth, IntermediateBufferHeight, filtered_texture_unit)
{
glBlendFunc(GL_SRC_ALPHA, GL_CONSTANT_COLOR);
@ -132,9 +130,9 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
RenderStage composite_render_stages[] =
{
{&composite_texture_, composite_input_shader_program_.get(), {0.0, 0.0, 0.0}},
// {&separated_texture_, composite_separation_filter_program_.get(), {0.0, 0.5, 0.5}},
{&separated_texture_, composite_separation_filter_program_.get(), {0.0, 0.5, 0.5}},
// {&filtered_y_texture_, composite_y_filter_shader_program_.get(), {0.0, 0.5, 0.5}},
// {&filtered_texture_, composite_chrominance_filter_shader_program_.get(), {0.0, 0.0, 0.0}},
{&filtered_texture_, composite_chrominance_filter_shader_program_.get(), {0.0, 0.0, 0.0}},
{nullptr}
};
@ -211,7 +209,6 @@ void OpenGLOutputBuilder::reset_all_OpenGL_state()
{
composite_input_shader_program_ = nullptr;
composite_separation_filter_program_ = nullptr;
composite_y_filter_shader_program_ = nullptr;
composite_chrominance_filter_shader_program_ = nullptr;
rgb_input_shader_program_ = nullptr;
rgb_filter_shader_program_ = nullptr;
@ -255,12 +252,12 @@ void OpenGLOutputBuilder::prepare_composite_input_shaders()
composite_separation_filter_program_->set_source_texture_unit(composite_texture_unit);
composite_separation_filter_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
composite_y_filter_shader_program_ = OpenGL::IntermediateShader::make_luma_filter_shader();
composite_y_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
composite_y_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
// composite_y_filter_shader_program_ = OpenGL::IntermediateShader::make_luma_filter_shader();
// composite_y_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
// composite_y_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
composite_chrominance_filter_shader_program_ = OpenGL::IntermediateShader::make_chroma_filter_shader();
composite_chrominance_filter_shader_program_->set_source_texture_unit(filtered_y_texture_unit);
composite_chrominance_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
composite_chrominance_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
}
@ -295,7 +292,7 @@ void OpenGLOutputBuilder::prepare_source_vertex_array()
void OpenGLOutputBuilder::prepare_output_shader()
{
output_shader_program_ = OpenGL::OutputShader::make_shader("", "texture(texID, srcCoordinatesVarying).rgb", false);
output_shader_program_->set_source_texture_unit(composite_texture_unit);//filtered_texture_unit);
output_shader_program_->set_source_texture_unit(filtered_texture_unit);
}
void OpenGLOutputBuilder::prepare_output_vertex_array()
@ -362,6 +359,7 @@ void OpenGLOutputBuilder::set_colour_space_uniforms()
}
if(composite_input_shader_program_) composite_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB);
if(composite_separation_filter_program_) composite_separation_filter_program_->set_colour_conversion_matrices(fromRGB, toRGB);
if(composite_chrominance_filter_shader_program_) composite_chrominance_filter_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB);
}
@ -374,7 +372,6 @@ void OpenGLOutputBuilder::set_timing_uniforms()
OpenGL::IntermediateShader *intermediate_shaders[] = {
composite_input_shader_program_.get(),
composite_separation_filter_program_.get(),
composite_y_filter_shader_program_.get(),
composite_chrominance_filter_shader_program_.get()
};
bool extends = false;
@ -390,15 +387,9 @@ void OpenGLOutputBuilder::set_timing_uniforms()
composite_separation_filter_program_->set_width_scalers(output_width, output_width);
composite_separation_filter_program_->set_separation_frequency(sample_cycles_per_line, colour_subcarrier_frequency);
}
if(composite_y_filter_shader_program_)
{
composite_y_filter_shader_program_->set_width_scalers(output_width, output_width);
composite_y_filter_shader_program_->set_filter_coefficients(sample_cycles_per_line, colour_subcarrier_frequency);
}
if(composite_chrominance_filter_shader_program_)
{
composite_chrominance_filter_shader_program_->set_width_scalers(output_width, output_width);
composite_chrominance_filter_shader_program_->set_filter_coefficients(sample_cycles_per_line, colour_subcarrier_frequency);
}
if(rgb_filter_shader_program_)
{

View File

@ -66,12 +66,11 @@ class OpenGLOutputBuilder {
GLsizei composite_src_output_y_;
std::unique_ptr<OpenGL::OutputShader> output_shader_program_;
std::unique_ptr<OpenGL::IntermediateShader> composite_input_shader_program_, composite_separation_filter_program_, composite_y_filter_shader_program_, composite_chrominance_filter_shader_program_;
std::unique_ptr<OpenGL::IntermediateShader> composite_input_shader_program_, composite_separation_filter_program_, composite_chrominance_filter_shader_program_;
std::unique_ptr<OpenGL::IntermediateShader> rgb_input_shader_program_, rgb_filter_shader_program_;
OpenGL::TextureTarget composite_texture_; // receives raw composite levels
OpenGL::TextureTarget separated_texture_; // receives unfiltered Y in the R channel plus unfiltered but demodulated chrominance in G and B
OpenGL::TextureTarget filtered_y_texture_; // receives filtered Y in the R channel plus unfiltered chrominance in G and B
OpenGL::TextureTarget separated_texture_; // receives filtered Y in the R channel plus unfiltered but demodulated chrominance in G and B
OpenGL::TextureTarget filtered_texture_; // receives filtered YIQ or YUV
std::unique_ptr<OpenGL::TextureTarget> framebuffer_; // the current pixel output

View File

@ -194,35 +194,51 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_luma_separat
"void main(void)"
"{"
// grab 11 samples
"vec4 samples[3] = vec4[]("
"vec4("
"vec3 samples[] = vec3[]("
"vec3("
"texture(texID, inputPositionsVarying[0]).r,"
"texture(texID, inputPositionsVarying[1]).r,"
"texture(texID, inputPositionsVarying[2]).r,"
"texture(texID, inputPositionsVarying[3]).r"
"),"
"vec4("
"vec3("
"texture(texID, inputPositionsVarying[4]).r,"
"texture(texID, inputPositionsVarying[5]).r,"
"texture(texID, inputPositionsVarying[6]).r,"
"texture(texID, inputPositionsVarying[7]).r"
"texture(texID, inputPositionsVarying[6]).r"
"),"
"vec4("
"vec3("
"texture(texID, inputPositionsVarying[7]).r,"
"texture(texID, inputPositionsVarying[8]).r,"
"texture(texID, inputPositionsVarying[9]).r,"
"texture(texID, inputPositionsVarying[10]).r,"
"0.0"
"texture(texID, inputPositionsVarying[10]).r"
")"
");"
"vec3 fixedWeights[] = vec3[]("
"vec3("
"-0.000918,"
"0.027278,"
"0.103969"
"),"
"vec3("
"0.202962,"
"0.250000,"
"0.202962"
"),"
"vec3("
"0.103969,"
"0.027278,"
"-0.000918"
")"
");"
// apply the low-pass filter to separate luma
"float luminance = "
"dot(vec3("
"dot(samples[0], weights[0]),"
"dot(samples[1], weights[1]),"
"dot(samples[2], weights[2])"
"dot(samples[0], fixedWeights[0]),"
"dot(samples[1], fixedWeights[1]),"
"dot(samples[2], fixedWeights[2])"
"), vec3(1.0));"
// define chroma to be whatever was here, minus luma
"float chrominance = 0.5 * (samples[1].y - luminance) / phaseAndAmplitudeVarying.y;"
"luminance /= (1.0 - phaseAndAmplitudeVarying.y);"
@ -251,40 +267,47 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_filter_shade
"{"
"vec3 samples[] = vec3[]("
"texture(texID, inputPositionsVarying[0]).rgb,"
"texture(texID, inputPositionsVarying[1]).rgb,"
"texture(texID, inputPositionsVarying[2]).rgb,"
"texture(texID, inputPositionsVarying[3]).rgb,"
"texture(texID, inputPositionsVarying[4]).rgb,"
"texture(texID, inputPositionsVarying[5]).rgb,"
"texture(texID, inputPositionsVarying[6]).rgb,"
"texture(texID, inputPositionsVarying[7]).rgb,"
"texture(texID, inputPositionsVarying[8]).rgb,"
"texture(texID, inputPositionsVarying[9]).rgb,"
"texture(texID, inputPositionsVarying[10]).rgb"
");"
"vec4 fixedWeights[2] = vec4[]("
"vec4("
"0.001298,"
"-0.038576,"
"0.287031,"
"0.500000"
"),"
"vec4("
"0.287031,"
"-0.038576,"
"0.001298,"
"0.0"
")"
");"
"vec4 chromaChannel1[] = vec4[]("
"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[8].g, samples[9].g, samples[10].g, 0.0)"
"vec4(samples[4].g, samples[5].g, samples[6].g, 0.0)"
");"
"vec4 chromaChannel2[] = vec4[]("
"vec4(samples[0].b, samples[1].b, samples[2].b, samples[3].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[4].b, samples[5].b, samples[6].b, 0.0)"
");"
"vec3 lumaChromaColour = vec3(samples[5].r,"
"dot(vec3("
"dot(chromaChannel1[0], weights[0]),"
"dot(chromaChannel1[1], weights[1]),"
"dot(chromaChannel1[2], weights[2])"
"), vec3(1.0)),"
"dot(vec3("
"dot(chromaChannel2[0], weights[0]),"
"dot(chromaChannel2[1], weights[1]),"
"dot(chromaChannel2[2], weights[2])"
"), vec3(1.0))"
"vec3 lumaChromaColour = vec3(samples[3].r,"
"dot(vec2("
"dot(chromaChannel1[0], fixedWeights[0]),"
"dot(chromaChannel1[1], fixedWeights[1])"
"), vec2(1.0)),"
"dot(vec2("
"dot(chromaChannel2[0], fixedWeights[0]),"
"dot(chromaChannel2[1], fixedWeights[1])"
"), vec2(1.0))"
");"
"vec3 lumaChromaColourInRange = (lumaChromaColour - vec3(0.0, 0.5, 0.5)) * vec3(1.0, 2.0, 2.0);"
@ -292,53 +315,6 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_filter_shade
"}", false, false);
}
std::unique_ptr<IntermediateShader> IntermediateShader::make_luma_filter_shader()
{
return make_shader(
"#version 150\n"
"in vec2 inputPositionsVarying[11];"
"uniform vec4 weights[3];"
"out vec3 fragColour;"
"uniform sampler2D texID;"
"uniform mat3 lumaChromaToRGB;"
"void main(void)"
"{"
"vec3 samples[] = vec3[]("
"texture(texID, inputPositionsVarying[0]).rgb,"
"texture(texID, inputPositionsVarying[1]).rgb,"
"texture(texID, inputPositionsVarying[2]).rgb,"
"texture(texID, inputPositionsVarying[3]).rgb,"
"texture(texID, inputPositionsVarying[4]).rgb,"
"texture(texID, inputPositionsVarying[5]).rgb,"
"texture(texID, inputPositionsVarying[6]).rgb,"
"texture(texID, inputPositionsVarying[7]).rgb,"
"texture(texID, inputPositionsVarying[8]).rgb,"
"texture(texID, inputPositionsVarying[9]).rgb,"
"texture(texID, inputPositionsVarying[10]).rgb"
");"
"vec4 luminance[] = vec4[]("
"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)"
");"
"fragColour = vec3("
"dot(vec3("
"dot(luminance[0], weights[0]),"
"dot(luminance[1], weights[1]),"
"dot(luminance[2], weights[2])"
"), vec3(1.0)),"
"samples[5].gb"
");"
// "fragColour = texture(texID, inputPositionsVarying[5]).rgb;"//lumaChromaToRGB * lumaChromaColourInRange;"
"}", false, false);
}
std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_filter_shader()
{
return make_shader(

View File

@ -44,11 +44,6 @@ public:
*/
static std::unique_ptr<IntermediateShader> make_chroma_filter_shader();
/*!
Constructs and returns an intermediate shader that will filter R while passing through G and B unchanged.
*/
static std::unique_ptr<IntermediateShader> make_luma_filter_shader();
/*!
Constructs and returns an intermediate shader that will filter R, G and B.
*/