New Shader Image Processing

Cleanup shaders and add image processing shader for source
This commit is contained in:
brunoherbelin
2020-04-25 23:58:49 +02:00
parent 0e24d1a083
commit 551acf25b9
24 changed files with 1009 additions and 65 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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()
{
}

View File

@@ -1,6 +1,8 @@
#ifndef IMAGEPROCESSINGSHADER_H
#define IMAGEPROCESSINGSHADER_H
#include <glm/glm.hpp>
#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;
};

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -35,6 +35,7 @@ public:
void visit(MediaPlayer& n);
void visit(Shader& n);
void visit(ImageShader& n);
void visit(ImageProcessingShader& n);
};
#endif // XMLVISITOR_H

View File

@@ -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<glm::mat4>();
modelview = glm::identity<glm::mat4>();
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);
}

View File

@@ -66,7 +66,7 @@ public:
protected:
ShadingProgram *program_;
glm::vec3 resolution;
glm::vec3 iResolution;
};

View File

@@ -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<ImageShader *>(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

View File

@@ -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;

View File

@@ -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&) {}
};

View File

@@ -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();
}

BIN
rsc/images/shadow.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
rsc/images/shadow_dark.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

462
rsc/mesh/circle.ply Normal file
View File

@@ -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

View File

@@ -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;

View File

@@ -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<EPSILON) );
return hsl;
}
float alphachromakey(vec3 color, vec3 colorKey, float delta)
{
// magic values
vec2 tol = vec2(0.5, 0.4*delta);
//convert from RGB to YCvCr/YUV
vec4 keyYuv = RGBtoYUV * vec4(colorKey, 1.0);
vec4 yuv = RGBtoYUV * vec4(color, 1.0);
// color distance in the UV (CbCr, PbPr) plane
vec2 dif = yuv.yz - keyYuv.yz;
float d = sqrt(dot(dif, dif));
// tolerance clamping
return max( (1.0 - step(d, tol.y)), step(tol.x, d) * (d - tol.x) / (tol.y - tol.x));
}
void main(void)
{
// deal with alpha separately
float ma = texture(iChannel0, vertexUV).a;
// float ma = texture(maskTexture, vertexUV).a * texture(iChannel0, vertexUV).a;
float alpha = clamp(ma * color.a, 0.0, 1.0);
// read color & apply basic filter
vec3 transformedRGB;
transformedRGB = apply_filter();
// chromakey
alpha -= mix( 0.0, 1.0 - alphachromakey( transformedRGB, chromakey.rgb, chromadelta), float(chromadelta > 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) );
}

View File

@@ -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()
{