From a073ab41dd9c120df87b10ddf18ee46c25e8e290 Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 27 Dec 2020 21:43:33 +0100 Subject: [PATCH] Improved procedural masks --- CMakeLists.txt | 1 + ImageShader.cpp | 3 ++- ImageShader.h | 2 +- View.cpp | 12 +-------- rsc/shaders/mask_box.fs | 30 +-------------------- rsc/shaders/mask_elipse.fs | 8 ++++++ rsc/shaders/mask_round.fs | 55 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 rsc/shaders/mask_round.fs diff --git a/CMakeLists.txt b/CMakeLists.txt index 29ad228..6a79975 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,6 +292,7 @@ set(VMIX_RSC_FILES ./rsc/shaders/image.fs ./rsc/shaders/mask_elipse.fs ./rsc/shaders/mask_box.fs + ./rsc/shaders/mask_round.fs ./rsc/shaders/image.vs ./rsc/shaders/imageprocessing.fs ./rsc/fonts/Hack-Regular.ttf diff --git a/ImageShader.cpp b/ImageShader.cpp index dd0c5c6..89e241d 100644 --- a/ImageShader.cpp +++ b/ImageShader.cpp @@ -9,7 +9,7 @@ static ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs"); -const char* MaskShader::mask_names[3] = { ICON_FA_EXPAND, ICON_FA_CIRCLE, ICON_FA_SQUARE }; +const char* MaskShader::mask_names[4] = { ICON_FA_EXPAND, ICON_FA_CIRCLE, ICON_FA_MINUS_CIRCLE, ICON_FA_SQUARE }; std::vector< ShadingProgram* > MaskShader::mask_programs; ImageShader::ImageShader(): Shader(), /*mask(0), custom_textureindex(0),*/ stipple(0.0) @@ -68,6 +68,7 @@ MaskShader::MaskShader(): Shader(), mode(0) if ( mask_programs.empty() ) { mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/simple.fs")); mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_elipse.fs")); + mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_round.fs")); mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_box.fs")); } // reset instance diff --git a/ImageShader.h b/ImageShader.h index f944a69..795cc05 100644 --- a/ImageShader.h +++ b/ImageShader.h @@ -47,7 +47,7 @@ public: float blur; glm::vec2 size; - static const char* mask_names[3]; + static const char* mask_names[4]; static std::vector< ShadingProgram* > mask_programs; }; diff --git a/View.cpp b/View.cpp index 0e7bcc6..7ce252f 100644 --- a/View.cpp +++ b/View.cpp @@ -2179,15 +2179,10 @@ void AppearanceView::adjustBackground() mask_node_->visible_ = edit_source_->maskShader()->mode > 0; mask_circle_->visible_ = edit_source_->maskShader()->mode == 1; - mask_square_->visible_ = edit_source_->maskShader()->mode == 2; + mask_square_->visible_ = edit_source_->maskShader()->mode >= 2; mask_node_->scale_ = scale * glm::vec3(edit_source_->maskShader()->size, 1.f); mask_corner_->scale_.y = mask_node_->scale_.x / mask_node_->scale_.y; -// crop_horizontal_->translation_.x = image_original_width * edit_source_->maskShader()->size.x; -// crop_vertical_->translation_.y = -edit_source_->maskShader()->size.y; -// crop_vertical_->translation_.x = -image_original_width - 0.12f; - - ///// Tests // preview_mask_->scale_ = edit_source_->mixingsurface_->scale_; @@ -2215,11 +2210,6 @@ void AppearanceView::adjustBackground() static glm::mat4 Tra = glm::scale(glm::translate(glm::identity(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); preview_checker_->shader()->iTransform = Ar * Tra; -// backgroundchecker_->scale_.x = image_original_width; -// glm::mat4 Ar = glm::scale(glm::identity(), glm::vec3(image_original_width, 1.f, 1.f) ); -// static glm::mat4 Tra = glm::scale(glm::translate(glm::identity(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); -// backgroundchecker_->shader()->iTransform = Ar * Tra; - } Source *AppearanceView::getEditOrCurrentSource() diff --git a/rsc/shaders/mask_box.fs b/rsc/shaders/mask_box.fs index 4ce9867..2d7b27e 100644 --- a/rsc/shaders/mask_box.fs +++ b/rsc/shaders/mask_box.fs @@ -15,33 +15,6 @@ uniform vec4 uv; uniform vec2 size; uniform float blur; -// See: http://www.iquilezles.org/www/articles/ellipsoids/ellipsoids.htm -float sdEllipse( in vec2 p, in vec2 e ) -{ - p = abs( p ); - - if( e.x0.0 ) s0=s; else s1=s; - } - - vec2 q = p*r/(r.y*s+r); - return length( p-q ) * (((p.y-q.y)<0.0)?-1.0:1.0); -} - float sdRoundBox( in vec2 p, in vec2 b, in float r ) { vec2 q = abs(p)-b+r; @@ -52,11 +25,10 @@ void main() { vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy; uv.x *= iResolution.x / iResolution.y; - // float d = sdEllipse( uv, vec2(size.x * iResolution.x/iResolution.y, size.y) ); float d = sdRoundBox( uv, vec2(size.x * iResolution.x/iResolution.y, size.y), blur * 0.5 ); - vec3 col = vec3(1.0- sign(d)); + vec3 col = vec3(1.0 - sign(d)); col *= 1.0 - exp( -60.0/ (blur * 100.f + 1.0) * abs(d)); FragColor = vec4( col, 1.0 ); diff --git a/rsc/shaders/mask_elipse.fs b/rsc/shaders/mask_elipse.fs index ce0374b..c3ec7e7 100644 --- a/rsc/shaders/mask_elipse.fs +++ b/rsc/shaders/mask_elipse.fs @@ -16,6 +16,13 @@ uniform vec2 size; uniform float blur; // See: http://www.iquilezles.org/www/articles/ellipsoids/ellipsoids.htm +float sdEllipsoid( in vec2 p, in vec2 r ) +{ + float k0 = length(p/r); + float k1 = length(p/(r*r)); + return k0*(k0-1.0)/k1; +} + float sdEllipse( in vec2 p, in vec2 e ) { p = abs( p ); @@ -46,6 +53,7 @@ void main() { vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy; uv.x *= iResolution.x / iResolution.y; + float d = sdEllipse( uv, vec2(size.x * iResolution.x/iResolution.y, size.y) ); vec3 col = vec3(1.0- sign(d)); diff --git a/rsc/shaders/mask_round.fs b/rsc/shaders/mask_round.fs new file mode 100644 index 0000000..80a2c36 --- /dev/null +++ b/rsc/shaders/mask_round.fs @@ -0,0 +1,55 @@ +#version 330 core + +out vec4 FragColor; + +in vec4 vertexColor; +in vec2 vertexUV; + +// from General Shader +uniform vec3 iResolution; // viewport resolution (in pixels) +uniform mat4 iTransform; // image transformation +uniform vec4 color; // drawing color +uniform vec4 uv; + +// Mask Shader +uniform vec2 size; +uniform float blur; +uniform float invert; + +float udSegment( in vec2 p, in vec2 a, in vec2 b ) +{ + vec2 ba = b-a; + vec2 pa = p-a; + float h =clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length(pa-h*ba); +} + +void main() +{ + float ar = iResolution.x / iResolution.y; + vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy; + uv.x *= ar; + + float th = 0.0; + vec2 v1; + vec2 v2; + vec2 rect = size; + rect.x *= ar; + + if(rect.x < rect.y) { + th = rect.x; + v1 = vec2(0.0, -rect.y + th) ; + v2 = vec2(0.0, rect.y - th) ; + } + else { + th = rect.y; + v1 = vec2(-rect.x + th, 0.0) ; + v2 = vec2( rect.x - th, 0.0) ; + } + float d = udSegment( uv, v1, v2 )- th; + + vec3 col = vec3(1.0- sign(d)); + col *= 1.0 - exp( -60.0/ (blur * 100.0 + 1.0) * abs(d)); + + FragColor = vec4( col, 1.0 ); +}