diff --git a/CMakeLists.txt b/CMakeLists.txt index 62a46fe..278f7f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,6 +202,7 @@ set(VMIX_SRCS Log.cpp Shader.cpp ImageShader.cpp + ImageProcessingShader.cpp Scene.cpp Primitives.cpp Mesh.cpp @@ -226,10 +227,11 @@ set(VMIX_SRCS ) set(VMIX_RSC_FILES - ./rsc/shaders/simple-shader.fs - ./rsc/shaders/simple-shader.vs - ./rsc/shaders/texture-shader.fs - ./rsc/shaders/texture-shader.vs + ./rsc/shaders/simple.fs + ./rsc/shaders/simple.vs + ./rsc/shaders/image.fs + ./rsc/shaders/image.vs + ./rsc/shaders/imageprocessing.fs ./rsc/fonts/Hack-Regular.ttf ./rsc/fonts/Roboto-Regular.ttf ./rsc/fonts/Roboto-Bold.ttf diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index d4ba684..4d1d53a 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -8,6 +8,7 @@ #include "Scene.h" #include "Primitives.h" #include "ImageShader.h" +#include "ImageProcessingShader.h" #include "MediaPlayer.h" #include "imgui.h" @@ -111,7 +112,11 @@ void ImGuiVisitor::visit(Shader &n) { ImGui::PushID(n.id()); - ImGui::ColorEdit3("color", glm::value_ptr(n.color) ) ; + if (ImGuiToolkit::ButtonIcon(14, 8)) { + n.color = glm::vec4(1.f, 1.f, 1.f, 1.f); + } + ImGui::SameLine(0, 10); + ImGui::ColorEdit3("Color", glm::value_ptr(n.color) ) ; ImGui::PopID(); } @@ -120,13 +125,13 @@ void ImGuiVisitor::visit(ImageShader &n) { ImGui::PushID(n.id()); - if (ImGuiToolkit::ButtonIcon(2, 1)) { + if (ImGuiToolkit::ButtonIcon(4, 1)) { n.brightness = 0.f; n.contrast = 0.f; } ImGui::SameLine(0, 10); float bc[2] = { n.brightness, n.contrast}; - if ( ImGui::SliderFloat2("filter", bc, -1.0, 1.0) ) + if ( ImGui::SliderFloat2("B & C", bc, -1.0, 1.0) ) { n.brightness = bc[0]; n.contrast = bc[1]; @@ -134,6 +139,63 @@ void ImGuiVisitor::visit(ImageShader &n) ImGui::PopID(); } +void ImGuiVisitor::visit(ImageProcessingShader &n) +{ + ImGui::PushID(n.id()); + + if (ImGuiToolkit::ButtonIcon(4, 1)) { + n.brightness = 0.f; + n.contrast = 0.f; + } + ImGui::SameLine(0, 10); + float bc[2] = { n.brightness, n.contrast}; + if ( ImGui::SliderFloat2("B & C", bc, -1.0, 1.0) ) + { + n.brightness = bc[0]; + n.contrast = bc[1]; + } + + if (ImGuiToolkit::ButtonIcon(2, 1)) n.saturation = 0.f; + ImGui::SameLine(0, 10); + ImGui::SliderFloat("Saturation", &n.saturation, -1.0, 1.0); + + if (ImGuiToolkit::ButtonIcon(12, 4)) n.hueshift = 0.f; + ImGui::SameLine(0, 10); + ImGui::SliderFloat("Hue shift", &n.hueshift, 0.0, 1.0); + + if (ImGuiToolkit::ButtonIcon(8, 1)) n.threshold = 0.f; + ImGui::SameLine(0, 10); + ImGui::SliderFloat("Threshold", &n.threshold, 0.0, 1.0); + + if (ImGuiToolkit::ButtonIcon(3, 1)) n.lumakey = 0.f; + ImGui::SameLine(0, 10); + ImGui::SliderFloat("Lumakey", &n.lumakey, 0.0, 1.0); + + if (ImGuiToolkit::ButtonIcon(18, 1)) n.nbColors = 0; + ImGui::SameLine(0, 10); + ImGui::SliderInt("Posterize", &n.nbColors, 0, 16); + + if (ImGuiToolkit::ButtonIcon(1, 7)) n.filter = 0; + ImGui::SameLine(0, 10); + ImGui::Combo("Filter", &n.filter, "None\0Blur\0Sharpen\0Edge\0Emboss\0Erode 3x3\0Erode 5x5\0Erode 7x7\0Dilate 3x3\0Dilate 5x5\0Dilate 7x7\0"); + + if (ImGuiToolkit::ButtonIcon(7, 1)) n.invert = 0; + ImGui::SameLine(0, 10); + ImGui::Combo("Invert", &n.invert, "None\0Invert color\0Invert Luminance\0"); + + if (ImGuiToolkit::ButtonIcon(14, 4)) n.chromadelta = 0.f; + ImGui::SameLine(0, 10); + ImGui::SliderFloat("Chromakey", &n.chromadelta, 0.0, 1.0); + + if (ImGuiToolkit::ButtonIcon(6, 4)) + n.chromakey = glm::vec4(0.f, 1.f, 0.f, 1.f); + ImGui::SameLine(0, 10); + ImGui::ColorEdit3("Chroma color", glm::value_ptr(n.chromakey) ) ; + + + ImGui::PopID(); +} + void ImGuiVisitor::visit(Scene &n) { ImGui::SetNextItemOpen(true, ImGuiCond_Once); diff --git a/ImGuiVisitor.h b/ImGuiVisitor.h index 0ed9aaf..8b6cf50 100644 --- a/ImGuiVisitor.h +++ b/ImGuiVisitor.h @@ -25,9 +25,10 @@ public: void visit(Mesh&) {} // Elements with attributes - void visit(MediaPlayer& n); - void visit(Shader& n); - void visit(ImageShader& n); + void visit(MediaPlayer& n) override; + void visit(Shader& n) override; + void visit(ImageShader& n) override; + void visit(ImageProcessingShader& n) override; }; #endif // IMGUIVISITOR_H diff --git a/ImageProcessingShader.cpp b/ImageProcessingShader.cpp index 4cb515b..0ec345f 100644 --- a/ImageProcessingShader.cpp +++ b/ImageProcessingShader.cpp @@ -1,7 +1,9 @@ +#include "defines.h" +#include "Visitor.h" +#include "Log.h" #include "ImageProcessingShader.h" - -ShadingProgram imageProcessingShadingProgram("shaders/processing-shader.vs", "shaders/texture-shader.fs"); +ShadingProgram imageProcessingShadingProgram("shaders/image.vs", "shaders/imageprocessing.fs"); ImageProcessingShader::ImageProcessingShader() { @@ -13,9 +15,25 @@ void ImageProcessingShader::use() { Shader::use(); + program_->setUniform("iChannelResolution[0]", iChannelResolution[0].x, iChannelResolution[0].y, iChannelResolution[0].z); + program_->setUniform("iChannelResolution[1]", iChannelResolution[1].x, iChannelResolution[1].y, iChannelResolution[1].z); + program_->setUniform("brightness", brightness); program_->setUniform("contrast", contrast); - program_->setUniform("stipple", stipple); + program_->setUniform("saturation", saturation); + program_->setUniform("hueshift", hueshift); + + program_->setUniform("threshold", threshold); + program_->setUniform("lumakey", lumakey); + program_->setUniform("nbColors", nbColors); + program_->setUniform("invert", invert); + program_->setUniform("filter", filter); + + program_->setUniform("gamma", gamma); + program_->setUniform("levels", levels); + program_->setUniform("chromakey", chromakey); + program_->setUniform("chromadelta", chromadelta); + } @@ -23,18 +41,28 @@ void ImageProcessingShader::reset() { Shader::reset(); + // no texture resolution yet + iChannelResolution[0] = glm::vec3(1.f); + iChannelResolution[1] = glm::vec3(1.f); + + // default values for image processing brightness = 0.f; contrast = 0.f; - stipple = 0.f; + saturation = 0.f; + hueshift = 0.f; + threshold = 0.f; + lumakey = 0.f; + nbColors = 0; + invert = 0; + filter = 0; + gamma = glm::vec4(1.f, 1.f, 1.f, 1.f); + levels = glm::vec4(0.f, 1.f, 0.f, 1.f); + chromakey = glm::vec4(0.f, 1.f, 0.f, 0.f); + chromadelta = 0.f; + } void ImageProcessingShader::accept(Visitor& v) { Shader::accept(v); v.visit(*this); } - - -::ImageProcessingShader() -{ - -} diff --git a/ImageProcessingShader.h b/ImageProcessingShader.h index 3a4f1d1..9567338 100644 --- a/ImageProcessingShader.h +++ b/ImageProcessingShader.h @@ -1,6 +1,8 @@ #ifndef IMAGEPROCESSINGSHADER_H #define IMAGEPROCESSINGSHADER_H +#include + #include "Shader.h" class ImageProcessingShader : public Shader @@ -8,15 +10,37 @@ class ImageProcessingShader : public Shader public: ImageProcessingShader(); - virtual ~ImageShader() {} + virtual ~ImageProcessingShader() {} virtual void use(); virtual void reset(); virtual void accept(Visitor& v); - float brightness; - float contrast; - float stipple; + // textures resolution + glm::vec3 iChannelResolution[2]; + + // color effects + float brightness; // [-1 1] + float contrast; // [-1 1] + float saturation; // [-1 1] + float hueshift; // [0 1] + float threshold; // [0 1] + float lumakey; // [0 1] + // gamma + glm::vec4 gamma; + glm::vec4 levels; + // discrete operations + int nbColors; + int invert; + // chroma key + glm::vec4 chromakey; + float chromadelta; + // filter + // [0] No filter + // [1 4] 4 x kernel operations; Blur, Sharpen, Edge, Emboss + // [5 10] 6 x convolutions: erosion 3, 5, 7, dilation 3, 5, 7 + int filter; + }; diff --git a/ImageShader.cpp b/ImageShader.cpp index 8fdd1eb..e39e95d 100644 --- a/ImageShader.cpp +++ b/ImageShader.cpp @@ -2,7 +2,7 @@ #include "Visitor.h" #include "ImageShader.h" -ShadingProgram imageShadingProgram("shaders/texture-shader.vs", "shaders/texture-shader.fs"); +ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs"); ImageShader::ImageShader() { diff --git a/PickingVisitor.h b/PickingVisitor.h index 325c8fa..1cf305c 100644 --- a/PickingVisitor.h +++ b/PickingVisitor.h @@ -31,11 +31,6 @@ public: void visit(LineSquare&); void visit(LineCircle& n); void visit(Mesh&){} - - // not picking other Elements with attributes - void visit(MediaPlayer&) {} - void visit(Shader&) {} - void visit(ImageShader&) {} }; #endif // PICKINGVISITOR_H diff --git a/SearchVisitor.h b/SearchVisitor.h index 21e84fb..d76788b 100644 --- a/SearchVisitor.h +++ b/SearchVisitor.h @@ -33,10 +33,6 @@ public: void visit(LineCircle&) {} void visit(Mesh&) {} - // not nodes - void visit(MediaPlayer&) {} - void visit(Shader&) {} - void visit(ImageShader&) {} }; #endif // SEARCHVISITOR_H diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index 1757440..a957c0e 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -5,6 +5,7 @@ #include "Primitives.h" #include "Mesh.h" #include "ImageShader.h" +#include "ImageProcessingShader.h" #include "MediaPlayer.h" #include "GstToolkit.h" @@ -157,13 +158,46 @@ void SessionVisitor::visit(ImageShader &n) // Shader of a textured type xmlCurrent_->SetAttribute("type", "ImageShader"); - XMLElement *filter = xmlDoc_->NewElement("filter"); + XMLElement *filter = xmlDoc_->NewElement("uniforms"); filter->SetAttribute("brightness", n.brightness); filter->SetAttribute("contrast", n.contrast); + filter->SetAttribute("stipple", n.stipple); xmlCurrent_->InsertEndChild(filter); } +void SessionVisitor::visit(ImageProcessingShader &n) +{ + // Shader of a textured type + xmlCurrent_->SetAttribute("type", "ImageProcessingShader"); + + XMLElement *filter = xmlDoc_->NewElement("uniforms"); + filter->SetAttribute("brightness", n.brightness); + filter->SetAttribute("contrast", n.contrast); + filter->SetAttribute("saturation", n.saturation); + filter->SetAttribute("hueshift", n.hueshift); + filter->SetAttribute("threshold", n.threshold); + filter->SetAttribute("lumakey", n.lumakey); + filter->SetAttribute("nbColors", n.nbColors); + filter->SetAttribute("invertMode", n.invert); + filter->SetAttribute("chromadelta", n.chromadelta); + filter->SetAttribute("filter", n.filter); + xmlCurrent_->InsertEndChild(filter); + + XMLElement *gamma = XMLElementFromGLM(xmlDoc_, n.gamma); + gamma->SetAttribute("type", "gamma"); + xmlCurrent_->InsertEndChild(gamma); + + XMLElement *levels = XMLElementFromGLM(xmlDoc_, n.levels); + levels->SetAttribute("type", "levels"); + xmlCurrent_->InsertEndChild(levels); + + XMLElement *chromakey = XMLElementFromGLM(xmlDoc_, n.chromakey); + chromakey->SetAttribute("type", "chromakey"); + xmlCurrent_->InsertEndChild(chromakey); + +} + void SessionVisitor::visit(LineStrip &n) { // Node of a different type diff --git a/SessionVisitor.h b/SessionVisitor.h index 5609ce0..221b711 100644 --- a/SessionVisitor.h +++ b/SessionVisitor.h @@ -35,6 +35,7 @@ public: void visit(MediaPlayer& n); void visit(Shader& n); void visit(ImageShader& n); + void visit(ImageProcessingShader& n); }; #endif // XMLVISITOR_H diff --git a/Shader.cpp b/Shader.cpp index 736622c..350cbc5 100644 --- a/Shader.cpp +++ b/Shader.cpp @@ -20,7 +20,7 @@ // Globals ShadingProgram *ShadingProgram::currentProgram_ = nullptr; -ShadingProgram simpleShadingProgram("shaders/simple-shader.vs", "shaders/simple-shader.fs"); +ShadingProgram simpleShadingProgram("shaders/simple.vs", "shaders/simple.fs"); // Blending presets for matching with Shader::BlendMode GLenum blending_equation[6] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD}; @@ -194,8 +194,8 @@ void Shader::use() program_->setUniform("modelview", modelview); program_->setUniform("color", color); - resolution = glm::vec3( Rendering::manager().currentAttrib().viewport, 0.f); - program_->setUniform("resolution", resolution); + iResolution = glm::vec3( Rendering::manager().currentAttrib().viewport, 0.f); + program_->setUniform("iResolution", iResolution); // Blending Function if ( blending != BLEND_NONE) { @@ -212,7 +212,7 @@ void Shader::reset() { projection = glm::identity(); modelview = glm::identity(); - resolution = glm::vec3(1280.f, 720.f, 0.f); + iResolution = glm::vec3(1280.f, 720.f, 0.f); color = glm::vec4(1.f, 1.f, 1.f, 1.f); } diff --git a/Shader.h b/Shader.h index f791e08..8c65547 100644 --- a/Shader.h +++ b/Shader.h @@ -66,7 +66,7 @@ public: protected: ShadingProgram *program_; - glm::vec3 resolution; + glm::vec3 iResolution; }; diff --git a/Source.cpp b/Source.cpp index fce032e..ef47ae9 100644 --- a/Source.cpp +++ b/Source.cpp @@ -7,6 +7,7 @@ #include "defines.h" #include "FrameBuffer.h" #include "ImageShader.h" +#include "ImageProcessingShader.h" #include "Resource.h" #include "Primitives.h" #include "Mesh.h" @@ -23,7 +24,6 @@ Source::Source(std::string name) : name_(""), initialized_(false) rename(name); // create groups for each view - // default rendering node groups_[View::RENDERING] = new Group; groups_[View::RENDERING]->scale_ = glm::vec3(5.f, 5.f, 1.f); // fit height full window @@ -35,12 +35,18 @@ Source::Source(std::string name) : name_(""), initialized_(false) groups_[View::MIXING]->addChild(frame); groups_[View::MIXING]->scale_ = glm::vec3(0.2f, 0.2f, 1.f); + // will be associated to nodes later + rendershader_ = new ImageProcessingShader(); + // add source to the list sources_.push_front(this); } Source::~Source() { + // delete shader + delete rendershader_; + // delete groups and their children delete groups_[View::RENDERING]; delete groups_[View::MIXING]; @@ -148,14 +154,6 @@ MediaSource::~MediaSource() // TODO verify that all surfaces and node is deleted in Source destructor } -ImageShader *MediaSource::shader() const -{ - if (!rendersurface_) - return nullptr; - - return static_cast(rendersurface_->shader()); -} - std::string MediaSource::uri() const { return uri_; @@ -182,9 +180,12 @@ void MediaSource::init() // create Frame buffer matching size of media player renderbuffer_ = new FrameBuffer(mediaplayer()->width(), mediaplayer()->height()); + // setup shader resolution for texture 0 + rendershader_->iChannelResolution[0] = glm::vec3(mediaplayer()->width(), mediaplayer()->height(), 0.f); + // create the surfaces to draw the frame buffer in the views // TODO Provide the source specific effect shader - rendersurface_ = new FrameBufferSurface(renderbuffer_); + rendersurface_ = new FrameBufferSurface(renderbuffer_, rendershader_); groups_[View::RENDERING]->addChild(rendersurface_); groups_[View::MIXING]->addChild(rendersurface_); @@ -225,7 +226,7 @@ void MediaSource::render(bool current) // read position of the mixing node and interpret this as transparency of render output float alpha = 1.0 - CLAMP( SQUARE( glm::length(groups_[View::MIXING]->translation_) ), 0.f, 1.f ); - rendersurface_->shader()->color.a = alpha; + rendershader_->color.a = alpha; // make Mixing Overlay visible if it is current source diff --git a/Source.h b/Source.h index dbce268..ce8c460 100644 --- a/Source.h +++ b/Source.h @@ -7,7 +7,7 @@ #include "View.h" -class ImageShader; +class ImageProcessingShader; class Surface; class FrameBuffer; class MediaPlayer; @@ -35,7 +35,7 @@ public: inline Group *group(View::Mode m) const { return groups_.at(m); } // every Source have a shader to control visual effects - virtual ImageShader *shader() const = 0; + inline ImageProcessingShader *shader() const { return rendershader_; } // every Source shall be rendered before draw virtual void render(bool current) = 0; @@ -64,10 +64,14 @@ protected: FrameBuffer *renderbuffer_; // the rendersurface draws the renderbuffer in the scene - // It is associated to the sourceshader for mixing effects + // It is associated to the rendershader for mixing effects // (aka visual effect applied in scene, not in render() ) FrameBufferSurface *rendersurface_; + // rendershader provides all image processing controls for + // mixing sources in the scene + ImageProcessingShader *rendershader_; + // static global list of sources static SourceList sources_; }; @@ -101,9 +105,6 @@ public: void render(bool current); - // Source interface - ImageShader *shader() const; - // Media specific interface std::string uri() const; MediaPlayer *mediaplayer() const; diff --git a/Visitor.h b/Visitor.h index 63a71a7..64d90fc 100644 --- a/Visitor.h +++ b/Visitor.h @@ -21,6 +21,7 @@ class Mesh; class MediaPlayer; class Shader; class ImageShader; +class ImageProcessingShader; // Declares the interface for the visitors class Visitor { @@ -42,9 +43,11 @@ public: virtual void visit (LineCircle&) = 0; virtual void visit (Mesh&) = 0; - virtual void visit (MediaPlayer&) = 0; - virtual void visit (Shader&) = 0; - virtual void visit (ImageShader&) = 0; + // not mandatory + virtual void visit (MediaPlayer&) {} + virtual void visit (Shader&) {} + virtual void visit (ImageShader&) {} + virtual void visit (ImageProcessingShader&) {} }; diff --git a/main.cpp b/main.cpp index 9565d0f..d6f5340 100644 --- a/main.cpp +++ b/main.cpp @@ -33,6 +33,7 @@ #include "RenderingManager.h" #include "UserInterfaceManager.h" #include "FrameBuffer.h" +#include "ImageProcessingShader.h" #include "MediaPlayer.h" #include "Scene.h" @@ -189,8 +190,14 @@ void drawScene() // draw GUI tree scene ImGui::Begin(IMGUI_TITLE_MAINWINDOW); static ImGuiVisitor v; - Mixer::manager().currentView()->scene.accept(v); +// Mixer::manager().currentView()->scene.accept(v); // Mixer::manager().getView(View::RENDERING)->scene.accept(v); + + Source *s = Mixer::manager().currentSource(); + if ( s != nullptr) { + s->shader()->accept(v); + } + ImGui::End(); } diff --git a/rsc/images/shadow.png b/rsc/images/shadow.png new file mode 100755 index 0000000..f0a350a Binary files /dev/null and b/rsc/images/shadow.png differ diff --git a/rsc/images/shadow_dark.png b/rsc/images/shadow_dark.png new file mode 100755 index 0000000..e721a80 Binary files /dev/null and b/rsc/images/shadow_dark.png differ diff --git a/rsc/mesh/circle.ply b/rsc/mesh/circle.ply new file mode 100644 index 0000000..1e1abaa --- /dev/null +++ b/rsc/mesh/circle.ply @@ -0,0 +1,462 @@ +ply +format ascii 1.0 +comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'circle.blend' +element vertex 192 +property float x +property float y +property float z +property uchar red +property uchar green +property uchar blue +property uchar alpha +element face 256 +property list uchar uint vertex_indices +end_header +-0.961670 -0.291719 0.000000 255 255 255 255 +-0.921437 -0.381671 0.000000 255 255 255 0 +-0.928456 -0.384579 0.000000 255 255 255 255 +-0.893037 -0.477338 0.000000 255 255 255 0 +-0.835589 -0.558322 0.000000 255 255 255 255 +-0.841959 -0.562579 0.000000 255 255 255 0 +0.782753 0.642390 0.000000 255 255 255 0 +0.835588 0.558323 0.000000 255 255 255 255 +0.776830 0.637529 0.000000 255 255 255 255 +0.099252 1.007728 0.000000 255 255 255 0 +0.196055 0.985644 0.000000 255 255 255 255 +0.098501 1.000103 0.000000 255 255 255 255 +-0.642389 0.782753 0.000000 255 255 255 0 +-0.710610 0.710610 0.000000 255 255 255 255 +-0.716027 0.716027 0.000000 255 255 255 0 +-0.291719 -0.961670 0.000000 255 255 255 255 +-0.381671 -0.921437 0.000000 255 255 255 0 +-0.289514 -0.954399 0.000000 255 255 255 0 +0.637529 -0.776830 0.000000 255 255 255 255 +0.554102 -0.829271 0.000000 255 255 255 0 +0.632709 -0.770957 0.000000 255 255 255 0 +1.000103 -0.098501 0.000000 255 255 255 255 +0.978192 -0.194574 0.000000 255 255 255 0 +0.992542 -0.097756 0.000000 255 255 255 0 +0.829271 0.554102 0.000000 255 255 255 0 +0.770957 0.632710 0.000000 255 255 255 0 +-0.776831 -0.637528 0.000000 255 255 255 255 +-0.829271 -0.554101 0.000000 255 255 255 0 +-0.770958 -0.632709 0.000000 255 255 255 0 +-0.637528 -0.776831 0.000000 255 255 255 255 +-0.705237 -0.705237 0.000000 255 255 255 0 +-0.632709 -0.770958 0.000000 255 255 255 0 +1.000103 0.098503 0.000000 255 255 255 255 +0.997356 0.000001 0.000000 255 255 255 0 +0.992542 0.097758 0.000000 255 255 255 0 +-0.473726 -0.886280 0.000000 255 255 255 255 +-0.554101 -0.829271 0.000000 255 255 255 0 +-0.470145 -0.879579 0.000000 255 255 255 0 +0.961669 0.291720 0.000000 255 255 255 255 +0.978192 0.194576 0.000000 255 255 255 0 +0.954399 0.289515 0.000000 255 255 255 0 +-0.098501 -1.000103 0.000000 255 255 255 255 +-0.194574 -0.978192 0.000000 255 255 255 0 +-0.097757 -0.992542 0.000000 255 255 255 0 +0.194573 0.978193 0.000000 255 255 255 0 +0.097756 0.992542 0.000000 255 255 255 0 +0.098502 -1.000103 0.000000 255 255 255 255 +0.000000 -0.997356 0.000000 255 255 255 0 +0.097757 -0.992542 0.000000 255 255 255 0 +0.637527 0.776832 0.000000 255 255 255 255 +0.705236 0.705238 0.000000 255 255 255 0 +0.632708 0.770959 0.000000 255 255 255 0 +0.473725 0.886280 0.000000 255 255 255 255 +0.554100 0.829272 0.000000 255 255 255 0 +0.470144 0.879580 0.000000 255 255 255 0 +0.776831 -0.637528 0.000000 255 255 255 255 +0.705238 -0.705237 0.000000 255 255 255 0 +0.770958 -0.632708 0.000000 255 255 255 0 +-0.961670 0.291719 0.000000 255 255 255 255 +-0.921437 0.381672 0.000000 255 255 255 0 +-0.954399 0.289514 0.000000 255 255 255 0 +0.291720 -0.961669 0.000000 255 255 255 255 +0.194575 -0.978192 0.000000 255 255 255 0 +0.289514 -0.954399 0.000000 255 255 255 0 +0.886280 -0.473726 0.000000 255 255 255 255 +0.829272 -0.554101 0.000000 255 255 255 0 +0.879580 -0.470144 0.000000 255 255 255 0 +0.381670 0.921437 0.000000 255 255 255 0 +0.384578 0.928457 0.000000 255 255 255 255 +-0.000000 0.997356 0.000000 255 255 255 0 +-0.000000 1.004954 0.000000 255 255 255 255 +0.710609 0.710610 0.000000 255 255 255 255 +-0.099252 -1.007728 0.000000 255 255 255 0 +0.000000 -1.004954 0.000000 255 255 255 255 +0.000000 -1.012616 0.000000 255 255 255 0 +0.099253 -1.007728 0.000000 255 255 255 0 +0.196057 -0.985644 0.000000 255 255 255 255 +0.197552 -0.993158 0.000000 255 255 255 0 +0.642390 -0.782753 0.000000 255 255 255 0 +0.558323 -0.835588 0.000000 255 255 255 255 +-0.293943 -0.969002 0.000000 255 255 255 0 +-0.196057 -0.985644 0.000000 255 255 255 255 +-0.197551 -0.993159 0.000000 255 255 255 0 +0.477339 -0.893037 0.000000 255 255 255 0 +0.384580 -0.928456 0.000000 255 255 255 255 +0.473727 -0.886280 0.000000 255 255 255 255 +-0.642389 -0.782753 0.000000 255 255 255 0 +-0.558322 -0.835589 0.000000 255 255 255 255 +-0.562579 -0.841959 0.000000 255 255 255 0 +-0.782753 -0.642389 0.000000 255 255 255 0 +-0.710610 -0.710610 0.000000 255 255 255 255 +-0.716027 -0.716027 0.000000 255 255 255 0 +-0.969001 -0.293943 0.000000 255 255 255 0 +-0.935535 -0.387511 0.000000 255 255 255 0 +-0.384579 -0.928456 0.000000 255 255 255 255 +-1.007728 -0.099252 0.000000 255 255 255 0 +-0.985644 -0.196057 0.000000 255 255 255 255 +-0.993159 -0.197551 0.000000 255 255 255 0 +0.558321 0.835589 0.000000 255 255 255 255 +-1.000103 -0.098501 0.000000 255 255 255 255 +-0.997356 0.000000 0.000000 255 255 255 0 +-0.992542 -0.097757 0.000000 255 255 255 0 +-0.978192 -0.194574 0.000000 255 255 255 0 +-0.954399 -0.289514 0.000000 255 255 255 0 +0.921437 0.381673 0.000000 255 255 255 0 +0.928456 0.384580 0.000000 255 255 255 255 +-1.000103 0.098502 0.000000 255 255 255 255 +-0.978192 0.194575 0.000000 255 255 255 0 +-0.992542 0.097757 0.000000 255 255 255 0 +0.293944 -0.969001 0.000000 255 255 255 0 +0.782754 -0.642389 0.000000 255 255 255 0 +0.710610 -0.710609 0.000000 255 255 255 255 +-0.477338 -0.893037 0.000000 255 255 255 0 +-0.387511 -0.935535 0.000000 255 255 255 0 +0.969002 -0.293943 0.000000 255 255 255 0 +0.985644 -0.196056 0.000000 255 255 255 255 +0.993159 -0.197551 0.000000 255 255 255 0 +0.642388 0.782754 0.000000 255 255 255 0 +-0.293943 0.969001 0.000000 255 255 255 0 +-0.196057 0.985644 0.000000 255 255 255 255 +-0.291719 0.961670 0.000000 255 255 255 255 +0.893037 -0.477337 0.000000 255 255 255 0 +0.928457 -0.384578 0.000000 255 255 255 255 +0.935535 -0.387510 0.000000 255 255 255 0 +0.969001 0.293944 0.000000 255 255 255 0 +0.985644 0.196058 0.000000 255 255 255 255 +-0.099253 1.007728 0.000000 255 255 255 0 +-0.098502 1.000103 0.000000 255 255 255 255 +0.562580 -0.841959 0.000000 255 255 255 0 +0.835589 -0.558322 0.000000 255 255 255 255 +0.841960 -0.562578 0.000000 255 255 255 0 +0.893036 0.477339 0.000000 255 255 255 0 +0.886279 0.473727 0.000000 255 255 255 255 +0.961670 -0.291718 0.000000 255 255 255 255 +1.007728 0.099254 0.000000 255 255 255 0 +1.004954 0.000001 0.000000 255 255 255 255 +0.387512 -0.935535 0.000000 255 255 255 0 +1.007728 -0.099252 0.000000 255 255 255 0 +0.716028 -0.716027 0.000000 255 255 255 0 +-0.969001 0.293943 0.000000 255 255 255 0 +-0.928456 0.384579 0.000000 255 255 255 255 +-0.384579 0.928456 0.000000 255 255 255 255 +-0.387511 0.935535 0.000000 255 255 255 0 +-0.893037 0.477338 0.000000 255 255 255 0 +-0.835589 0.558322 0.000000 255 255 255 255 +-0.886280 0.473726 0.000000 255 255 255 255 +0.841958 0.562580 0.000000 255 255 255 0 +0.935534 0.387512 0.000000 255 255 255 0 +-0.782753 0.642389 0.000000 255 255 255 0 +-0.776831 0.637529 0.000000 255 255 255 255 +0.993158 0.197553 0.000000 255 255 255 0 +-0.558322 0.835589 0.000000 255 255 255 255 +-0.637528 0.776831 0.000000 255 255 255 255 +1.012616 0.000001 0.000000 255 255 255 0 +-0.477338 0.893037 0.000000 255 255 255 0 +-0.473726 0.886280 0.000000 255 255 255 255 +0.477337 0.893037 0.000000 255 255 255 0 +0.293942 0.969002 0.000000 255 255 255 0 +0.291718 0.961670 0.000000 255 255 255 255 +-0.197552 0.993158 0.000000 255 255 255 0 +-0.000000 1.012616 0.000000 255 255 255 0 +-0.935535 0.387511 0.000000 255 255 255 0 +-0.886280 -0.473726 0.000000 255 255 255 255 +0.197550 0.993159 0.000000 255 255 255 0 +-1.004954 0.000000 0.000000 255 255 255 255 +-0.841959 0.562579 0.000000 255 255 255 0 +-1.007728 0.099253 0.000000 255 255 255 0 +-0.985644 0.196057 0.000000 255 255 255 255 +0.387510 0.935535 0.000000 255 255 255 0 +0.716026 0.716028 0.000000 255 255 255 0 +0.562578 0.841960 0.000000 255 255 255 0 +-0.562579 0.841959 0.000000 255 255 255 0 +-0.194575 0.978192 0.000000 255 255 255 0 +-0.705237 0.705237 0.000000 255 255 255 0 +-0.829271 0.554101 0.000000 255 255 255 0 +-0.879579 -0.470145 0.000000 255 255 255 0 +-1.012616 0.000000 0.000000 255 255 255 0 +-0.993158 0.197552 0.000000 255 255 255 0 +-0.381672 0.921437 0.000000 255 255 255 0 +0.381672 -0.921437 0.000000 255 255 255 0 +-0.289514 0.954399 0.000000 255 255 255 0 +0.470145 -0.879579 0.000000 255 255 255 0 +-0.470145 0.879579 0.000000 255 255 255 0 +-0.770958 0.632709 0.000000 255 255 255 0 +0.289512 0.954400 0.000000 255 255 255 0 +0.921437 -0.381671 0.000000 255 255 255 0 +-0.097757 0.992542 0.000000 255 255 255 0 +-0.554101 0.829271 0.000000 255 255 255 0 +-0.632709 0.770958 0.000000 255 255 255 0 +0.954399 -0.289513 0.000000 255 255 255 0 +-0.879579 0.470145 0.000000 255 255 255 0 +0.879579 0.470146 0.000000 255 255 255 0 +3 0 1 2 +3 3 4 5 +3 6 7 8 +3 9 10 11 +3 12 13 14 +3 15 16 17 +3 18 19 20 +3 21 22 23 +3 8 24 25 +3 26 27 28 +3 29 30 31 +3 32 33 34 +3 35 36 37 +3 38 39 40 +3 41 42 43 +3 11 44 45 +3 46 47 48 +3 49 50 51 +3 52 53 54 +3 55 56 57 +3 58 59 60 +3 61 62 63 +3 64 65 66 +3 52 67 68 +3 11 69 70 +3 8 50 71 +3 72 73 74 +3 75 76 77 +3 78 79 18 +3 80 81 82 +3 83 84 85 +3 86 87 88 +3 89 90 91 +3 75 73 46 +3 72 81 41 +3 92 2 93 +3 80 94 15 +3 95 96 97 +3 49 53 98 +3 99 100 101 +3 0 102 103 +3 38 104 105 +3 106 107 108 +3 109 76 61 +3 110 111 55 +3 112 94 113 +3 114 115 116 +3 117 71 49 +3 118 119 120 +3 121 122 123 +3 124 125 38 +3 126 70 127 +3 83 79 128 +3 110 129 130 +3 131 105 132 +3 114 122 133 +3 134 135 32 +3 121 129 64 +3 109 84 136 +3 137 115 21 +3 78 111 138 +3 139 140 58 +3 118 141 142 +3 143 144 145 +3 131 7 146 +3 124 105 147 +3 148 13 149 +3 134 125 150 +3 12 151 152 +3 137 135 153 +3 154 141 155 +3 156 98 52 +3 157 68 158 +3 126 119 159 +3 9 70 160 +3 143 140 161 +3 3 2 162 +3 157 10 163 +3 95 164 99 +3 92 96 0 +3 148 144 165 +3 166 167 106 +3 156 68 168 +3 6 71 169 +3 117 98 170 +3 154 151 171 +3 127 172 119 +3 152 173 13 +3 149 174 144 +3 162 1 175 +3 112 87 35 +3 166 164 176 +3 139 167 177 +3 89 4 26 +3 86 90 29 +3 120 178 141 +3 132 24 7 +3 85 19 79 +3 99 102 96 +3 61 179 84 +3 35 16 94 +3 120 172 180 +3 85 179 181 +3 155 178 182 +3 149 173 183 +3 158 67 184 +3 162 27 4 +3 64 185 122 +3 106 100 164 +3 41 47 73 +3 32 39 125 +3 133 22 115 +3 127 69 186 +3 155 187 151 +3 26 30 90 +3 152 187 188 +3 158 44 10 +3 46 62 76 +3 18 56 111 +3 21 33 135 +3 29 36 87 +3 133 185 189 +3 58 107 167 +3 55 65 129 +3 145 174 190 +3 145 59 140 +3 132 104 191 +3 15 42 81 +3 0 103 1 +3 3 162 4 +3 6 146 7 +3 9 163 10 +3 12 152 13 +3 15 94 16 +3 18 79 19 +3 21 115 22 +3 8 7 24 +3 26 4 27 +3 29 90 30 +3 32 135 33 +3 35 87 36 +3 38 125 39 +3 41 81 42 +3 11 10 44 +3 46 73 47 +3 49 71 50 +3 52 98 53 +3 55 111 56 +3 58 140 59 +3 61 76 62 +3 64 129 65 +3 52 54 67 +3 11 45 69 +3 8 25 50 +3 72 41 73 +3 75 46 76 +3 78 128 79 +3 80 15 81 +3 83 136 84 +3 86 29 87 +3 89 26 90 +3 75 74 73 +3 72 82 81 +3 92 0 2 +3 80 113 94 +3 95 99 96 +3 49 51 53 +3 99 164 100 +3 0 96 102 +3 38 40 104 +3 106 167 107 +3 109 77 76 +3 110 138 111 +3 112 35 94 +3 114 133 115 +3 117 169 71 +3 118 159 119 +3 121 64 122 +3 124 150 125 +3 126 160 70 +3 83 85 79 +3 110 55 129 +3 131 147 105 +3 114 123 122 +3 134 153 135 +3 121 130 129 +3 109 61 84 +3 137 116 115 +3 78 18 111 +3 139 161 140 +3 118 120 141 +3 143 165 144 +3 131 132 7 +3 124 38 105 +3 148 14 13 +3 134 32 125 +3 12 171 151 +3 137 21 135 +3 154 142 141 +3 156 170 98 +3 157 168 68 +3 126 127 119 +3 9 11 70 +3 143 145 140 +3 3 93 2 +3 157 158 10 +3 95 176 164 +3 92 97 96 +3 148 149 144 +3 166 177 167 +3 156 52 68 +3 6 8 71 +3 117 49 98 +3 154 155 151 +3 127 186 172 +3 152 188 173 +3 149 183 174 +3 162 2 1 +3 112 88 87 +3 166 106 164 +3 139 58 167 +3 89 5 4 +3 86 91 90 +3 120 180 178 +3 132 191 24 +3 85 181 19 +3 99 101 102 +3 61 63 179 +3 35 37 16 +3 120 119 172 +3 85 84 179 +3 155 141 178 +3 149 13 173 +3 158 68 67 +3 162 175 27 +3 64 66 185 +3 106 108 100 +3 41 43 47 +3 32 34 39 +3 133 189 22 +3 127 70 69 +3 155 182 187 +3 26 28 30 +3 152 151 187 +3 158 184 44 +3 46 48 62 +3 18 20 56 +3 21 23 33 +3 29 31 36 +3 133 122 185 +3 58 60 107 +3 55 57 65 +3 145 144 174 +3 145 190 59 +3 132 105 104 +3 15 17 42 diff --git a/rsc/shaders/texture-shader.fs b/rsc/shaders/image.fs similarity index 77% rename from rsc/shaders/texture-shader.fs rename to rsc/shaders/image.fs index 7b40953..6426dd3 100644 --- a/rsc/shaders/texture-shader.fs +++ b/rsc/shaders/image.fs @@ -5,17 +5,18 @@ out vec4 FragColor; in vec4 vertexColor; in vec2 vertexUV; -uniform sampler2D sourceTexture; +uniform sampler2D iChannel0; // input channel (texture id). +uniform vec3 iResolution; // viewport resolution (in pixels) + uniform vec4 color; uniform float contrast; uniform float brightness; uniform float stipple; -uniform vec3 resolution; // viewport resolution (in pixels) void main() { // color is a mix of texture (manipulated with brightness & contrast), vertex and uniform colors - vec4 textureColor = texture(sourceTexture, vertexUV); + vec4 textureColor = texture(iChannel0, vertexUV); vec3 RGB = mix(vec3(0.62), textureColor.rgb, contrast + 1.0) + brightness; RGB *= vertexColor.rgb * color.rgb; diff --git a/rsc/shaders/texture-shader.vs b/rsc/shaders/image.vs similarity index 100% rename from rsc/shaders/texture-shader.vs rename to rsc/shaders/image.vs diff --git a/rsc/shaders/imageprocessing.fs b/rsc/shaders/imageprocessing.fs new file mode 100644 index 0000000..0541d49 --- /dev/null +++ b/rsc/shaders/imageprocessing.fs @@ -0,0 +1,326 @@ +#version 330 core + +/* +** Gamma correction +** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/ +*/ +#define GammaCorrection(color, gamma) pow( color, 1.0 / vec3(gamma)) + +/* +** Levels control (input (+gamma), output) +** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/ +*/ +#define LevelsControlInputRange(color, minInput, maxInput) min(max(color - vec3(minInput), 0.0) / (vec3(maxInput) - vec3(minInput)), 1.0) +#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma) +#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color) +#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput) + +#define ONETHIRD 0.333333 +#define TWOTHIRD 0.666666 +#define EPSILON 0.000001 + +out vec4 FragColor; + +// from vertex shader (interpolated) +in vec4 vertexColor; +in vec2 vertexUV; + +// general shader uniforms +uniform vec4 color; + +// image processing specific +uniform sampler2D iChannel0; // input channel (texture id). +uniform sampler2D iChannel1; +uniform vec3 iChannelResolution[2]; // input channel resolution (in pixels) +uniform vec3 iResolution; // viewport resolution (in pixels) + +uniform float contrast; +uniform float brightness; +uniform float saturation; +uniform vec4 gamma; +uniform vec4 levels; +uniform float hueshift; +uniform vec4 chromakey; +uniform float chromadelta; +uniform float threshold; +uniform float lumakey; +uniform int nbColors; +uniform int invert; +uniform int filter; + +// conversion between rgb and YUV +const mat4 RGBtoYUV = mat4(0.257, 0.439, -0.148, 0.0, + 0.504, -0.368, -0.291, 0.0, + 0.098, -0.071, 0.439, 0.0, + 0.0625, 0.500, 0.500, 1.0 ); + +const mat3 KERNEL[5] = mat3[5]( mat3( 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0), + mat3( 0.0625, 0.125, 0.0625, + 0.125, 0.25, 0.125, + 0.0625, 0.125, 0.0625), + mat3( -1.0, -1.0, -1.0, + -1.0, 9.0, -1.0, + -1.0, -1.0, -1.0), + mat3( -2.0, 1.0, -2.0, + 1.0, 4.0, 1.0, + -2.0, 1.0, -2.0), + mat3( -2.0, -1.0, 0.0, + -1.0, 1.0, 1.0, + 0.0, 1.0, 2.0) + ); + +vec3 erosion(int N, vec2 filter_step) +{ + vec3 minValue = vec3(1.0); + + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0,0.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0,-1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0, 0.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (1.0, 0.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, minValue); + if (N == 3) + return minValue; + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0,-2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (1.0,-2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0,2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0, 2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (1.0, 2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-2.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 1.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-2.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 1.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 2.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-2.0, 0.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 0.0) * filter_step ).rgb, minValue); + if (N == 5) + return minValue; + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0,-3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (1.0,-3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-1.0,3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (0.0, 3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (1.0, 3.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-2.0, 2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-2.0, -2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 2.0, -2.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-3.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (3.0, -1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-3.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 3.0, 1.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 (-3.0, 0.0) * filter_step ).rgb, minValue); + minValue = min(texture2D(iChannel0, vertexUV + vec2 ( 3.0, 0.0) * filter_step ).rgb, minValue); + + return minValue; +} + +vec3 dilation(int N, vec2 filter_step) +{ + vec3 maxValue = vec3(0.0); + + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0, 0.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0,-1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0, 0.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (1.0, 0.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0, 1.0) * filter_step ).rgb, maxValue); + if (N == 3) + return maxValue; + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0, -2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0,-2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (1.0,-2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0,2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0, 2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (1.0, 2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-2.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 1.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-2.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 1.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 2.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-2.0, 0.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 0.0) * filter_step ).rgb, maxValue); + if (N == 5) + return maxValue; + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0, -3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0,-3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (1.0,-3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-1.0,3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (0.0, 3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (1.0, 3.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-2.0, 2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 2.0, 2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-2.0, -2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 2.0, -2.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-3.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (3.0, -1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-3.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 3.0, 1.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 (-3.0, 0.0) * filter_step ).rgb, maxValue); + maxValue = max(texture2D(iChannel0, vertexUV + vec2 ( 3.0, 0.0) * filter_step ).rgb, maxValue); + + return maxValue; +} + +vec3 convolution(mat3 kernel, vec2 filter_step) +{ + int i = 0, j = 0; + vec3 sum = vec3(0.0); + + for (i = 0; i<3; ++i) + for (j = 0; j<3; ++j) + sum += texture(iChannel0, vertexUV + filter_step * vec2 (i-1, j-1) ).rgb * kernel[i][j]; + + return sum; +} + +vec3 apply_filter() { + + vec2 filter_step = vec2( 1.f / iChannelResolution[0].x, 1.f / iChannelResolution[0].y); +// vec2 filter_step = vec2( 1.f / 1280.0, 1.f / 720.0); + + if (filter < 1 || filter > 10) + return texture(iChannel0, vertexUV).rgb; + else if (filter < 5) + return convolution( KERNEL[filter], filter_step); + else if (filter < 8) + return erosion( 3 + (filter -5) * 2, filter_step); + else + return dilation( 3 + (filter -8) * 2, filter_step); +} + +/* +** Hue, saturation, luminance <=> Red Green Blue +*/ + +float HueToRGB(float f1, float f2, float hue) +{ + float res; + + hue += mix( -float( hue > 1.0 ), 1.0, float(hue < 0.0) ); + + res = mix( f1, mix( clamp( f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0, 0.0, 1.0) , mix( f2, clamp(f1 + (f2 - f1) * 6.0 * hue, 0.0, 1.0), float((6.0 * hue) < 1.0)), float((2.0 * hue) < 1.0)), float((3.0 * hue) < 2.0) ); + + return res; +} + +vec3 HSV2RGB(vec3 hsl) +{ + vec3 rgb; + float f1, f2; + + f2 = mix( (hsl.z + hsl.y) - (hsl.y * hsl.z), hsl.z * (1.0 + hsl.y), float(hsl.z < 0.5) ); + + f1 = 2.0 * hsl.z - f2; + + rgb.r = HueToRGB(f1, f2, hsl.x + ONETHIRD); + rgb.g = HueToRGB(f1, f2, hsl.x); + rgb.b = HueToRGB(f1, f2, hsl.x - ONETHIRD); + + rgb = mix( rgb, vec3(hsl.z), float(hsl.y < EPSILON)); + + return rgb; +} + +vec3 RGB2HSV( vec3 color ) +{ + vec3 hsl = vec3(0.0); // init to 0 + + float fmin = min(min(color.r, color.g), color.b); //Min. value of RGB + float fmax = max(max(color.r, color.g), color.b); //Max. value of RGB + float delta = fmax - fmin + EPSILON; //Delta RGB value + + vec3 deltaRGB = ( ( vec3(fmax) - color ) / 6.0 + vec3(delta) / 2.0 ) / delta ; + + hsl.z = (fmax + fmin) / 2.0; // Luminance + + hsl.y = delta / ( EPSILON + mix( 2.0 - fmax - fmin, fmax + fmin, float(hsl.z < 0.5)) ); + + hsl.x = mix( hsl.x, TWOTHIRD + deltaRGB.g - deltaRGB.r, float(color.b == fmax)); + hsl.x = mix( hsl.x, ONETHIRD + deltaRGB.r - deltaRGB.b, float(color.g == fmax)); + hsl.x = mix( hsl.x, deltaRGB.b - deltaRGB.g, float(color.r == fmax)); + + hsl.x += mix( - float( hsl.x > 1.0 ), 1.0, float(hsl.x < 0.0) ); + + hsl = mix ( hsl, vec3(-1.0, 0.0, hsl.z), float(delta 0.0001) ); + + // color transformation + transformedRGB = mix(vec3(0.62), transformedRGB, contrast + 1.0) + brightness; + transformedRGB = LevelsControl(transformedRGB, levels.x, gamma.rgb * gamma.a, levels.y, levels.z, levels.w); + + // RGB invert + transformedRGB = vec3(float(invert==1)) + ( transformedRGB * vec3(1.0 - 2.0 * float(invert==1)) ); + + // Convert to HSL + vec3 transformedHSL = RGB2HSV( transformedRGB ); + + // Luminance invert + transformedHSL.z = float(invert==2) + transformedHSL.z * (1.0 - 2.0 * float(invert==2) ); + + // perform hue shift + transformedHSL.x = transformedHSL.x + hueshift; + + // Saturation + transformedHSL.y *= saturation + 1.0; + + // perform reduction of colors + transformedHSL = mix( transformedHSL, floor(transformedHSL * vec3(nbColors)) / vec3(nbColors-1), float( nbColors > 0 ) ); + + // luma key + alpha -= mix( 0.0, step( transformedHSL.z, lumakey ), float(lumakey > EPSILON)); + + // level threshold + transformedHSL = mix( transformedHSL, vec3(0.0, 0.0, step( transformedHSL.z, threshold )), float(threshold > EPSILON)); + + // after operations on HSL, convert back to RGB + transformedRGB = HSV2RGB(transformedHSL); + + // apply base color and alpha for final fragment color + FragColor = vec4(transformedRGB * vertexColor.rgb * color.rgb, clamp(alpha, 0.0, 1.0) ); + +} + + diff --git a/rsc/shaders/simple-shader.fs b/rsc/shaders/simple.fs similarity index 71% rename from rsc/shaders/simple-shader.fs rename to rsc/shaders/simple.fs index 2a16f3f..d18a94b 100644 --- a/rsc/shaders/simple-shader.fs +++ b/rsc/shaders/simple.fs @@ -5,7 +5,7 @@ out vec4 FragColor; in vec4 vertexColor; uniform vec4 color; // drawing color -uniform vec3 resolution; // viewport resolution (in pixels) +uniform vec3 iResolution; // viewport resolution (in pixels) void main() { diff --git a/rsc/shaders/simple-shader.vs b/rsc/shaders/simple.vs similarity index 100% rename from rsc/shaders/simple-shader.vs rename to rsc/shaders/simple.vs