From 876c002616ec29e2acbdb28023c7275f723fb6b9 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Fri, 22 Feb 2019 02:26:25 +0100 Subject: [PATCH] all blending modes for pattern and dual brush --- data/layout.xml | 10 ++--- data/shaders/comp-draw.glsl | 6 +-- data/shaders/include/blend-stroke.glsl | 58 +++++++++++++++++++++++--- data/shaders/stroke.glsl | 4 +- src/abr.h | 6 +-- src/app_vr.cpp | 1 + src/brush.h | 4 +- src/canvas.cpp | 2 + src/node_canvas.cpp | 1 + src/node_stroke_preview.cpp | 3 ++ src/shader.h | 1 + 11 files changed, 75 insertions(+), 21 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index c948d72..8497fbb 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -31,7 +31,7 @@ - + @@ -217,7 +217,7 @@ - + @@ -341,10 +341,10 @@ - + - + @@ -429,7 +429,7 @@ - + diff --git a/data/shaders/comp-draw.glsl b/data/shaders/comp-draw.glsl index 6b2bc10..81b4007 100644 --- a/data/shaders/comp-draw.glsl +++ b/data/shaders/comp-draw.glsl @@ -64,14 +64,14 @@ void main() if (pattern_contr != 0.5) patt = contrast1(patt, pattern_contr); //mediump float pa = (1.0 - patt) * pow(pattern_depth, 0.25) + (stroke.a * pattern_depth * 10.0); - mediump float pa = pow((1.0 - patt), max(1.0, (1.0 - pattern_depth) * 10.0)) * pow(pattern_depth, 0.25) + (stroke.a * pattern_depth * 5.0); - stroke.a = mix(pa * stroke.a, stroke.a, 0.0); + //mediump float pa = pow((1.0 - patt), max(1.0, (1.0 - pattern_depth) * 10.0)) * pow(pattern_depth, 0.25) + (stroke.a * pattern_depth * 5.0); + stroke.a = blend_stroke(stroke.a, patt, pattern_depth, patt_blend_mode); } if (use_dual) { mediump vec4 dual = texture(tex_dual, uv); - stroke.a = blend_stroke(stroke.a, dual.a * dual_alpha, dual_blend_mode); + stroke.a = blend_stroke(stroke.a, dual.a, dual_alpha, dual_blend_mode); } stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha; diff --git a/data/shaders/include/blend-stroke.glsl b/data/shaders/include/blend-stroke.glsl index dd581f8..277b718 100644 --- a/data/shaders/include/blend-stroke.glsl +++ b/data/shaders/include/blend-stroke.glsl @@ -1,9 +1,55 @@ -mediump float blend_stroke(mediump float base, mediump float stroke, int mode) +mediump float blend_stroke_screen(mediump float base, mediump float stroke) { - if (mode == 0) /* normal */ return (base + stroke) * 0.5; - else if (mode == 1) /* multiply */ return base * stroke; - else if (mode == 2) /* screen */ return 1.0-(1.0-base)*(1.0-stroke); - else if (mode == 3) /* color-dodge */ return base/(1.0-stroke); - else if (mode == 4) /* overlay */ return mix(2.0*base*stroke, 1.0-2.0*(1.0-base)*(1.0-stroke), floor(base*2.0)); + return clamp(base + stroke - (base * stroke), 0.0, 1.0); +} + +mediump float blend_stroke_hard_light(mediump float base, mediump float stroke) +{ + if (stroke < 0.5) + return max(1.0, base * (stroke * 2.0)); // multiply + else + return blend_stroke_screen(base, 2.0 * stroke - 1.0); +} + +mediump float blend_stroke_hard_mix(mediump float base, mediump float stroke) +{ + return base + stroke > 0.5 ? 1.0 : 0.0; +} + +mediump float blend_stroke_color_dodge(mediump float base, mediump float stroke) +{ + if (base == 0.0) + return 0.0; + else if (stroke == 1.0) + return 1.0; + else + return min(1.0, base / (1.0 - stroke)); +} + +mediump float blend_stroke_linear_height(mediump float base, mediump float stroke, mediump float depth) +{ + mediump float partial = (1.0 - stroke) * pow(depth, 0.25) + (base * depth * 10.0); + return stroke * partial; +} + +mediump float blend_stroke_height(mediump float base, mediump float stroke, mediump float depth) +{ + mediump float A = pow((1.0 - stroke), max(1.0, (1.0 - depth) * 10.0)) * pow(depth, 0.25); + mediump float B = (base * depth * 5.0); + return stroke * (A + B); +} + +mediump float blend_stroke(mediump float base, mediump float stroke, mediump float depth, int mode) +{ + if (mode == 0) /* normal */ return mix(base, stroke, depth); + else if (mode == 1) /* multiply */ return mix(base, base * stroke, depth); + else if (mode == 2) /* subtract */ return mix(base, max(0.0, base - stroke), depth); + else if (mode == 3) /* darken */ return mix(base, min(base, stroke), depth); + else if (mode == 4) /* overlay */ return mix(base, blend_stroke_hard_light(stroke, base), depth); + else if (mode == 5) /* col-dodge */ return mix(base, blend_stroke_color_dodge(stroke, base), depth); + else if (mode == 6) /* lin-burn */ return mix(base, clamp(stroke + base - 1.0, 0.0, 1.0), depth); + else if (mode == 7) /* hard-mix */ return mix(base, blend_stroke_hard_mix(base, stroke), depth); + else if (mode == 8) /* lin-height */ return blend_stroke_linear_height(base, stroke, depth); + else if (mode == 9) /* height */ return blend_stroke_height(base, stroke, depth); else return 1.0; } diff --git a/data/shaders/stroke.glsl b/data/shaders/stroke.glsl index 4c6e074..95e785d 100644 --- a/data/shaders/stroke.glsl +++ b/data/shaders/stroke.glsl @@ -22,6 +22,7 @@ void main() #include "include/ext-fb-fetch.glsl" #include "include/rand.glsl" #include "include/color.glsl" +#include "include/blend-stroke.glsl" uniform mediump sampler2D tex; uniform mediump sampler2D tex_bg; @@ -41,6 +42,7 @@ uniform mediump float pattern_contr; uniform mediump float pattern_depth; uniform mediump vec2 pattern_offset; uniform mediump bool pattern_invert; +uniform mediump int patt_blend_mode; in mediump vec2 uv; in mediump vec2 uv_2; @@ -68,7 +70,7 @@ void main() patt = brightness1(patt, 1.0 - pattern_bright); if (pattern_contr != 0.5) patt = contrast1(patt, pattern_contr); - fg.a = mix(fg.a, fg.a * patt, pattern_depth); + fg.a = blend_stroke(fg.a, patt, pattern_depth, patt_blend_mode); } #if defined(GL_EXT_shader_framebuffer_fetch) diff --git a/src/abr.h b/src/abr.h index d437572..f624672 100644 --- a/src/abr.h +++ b/src/abr.h @@ -24,14 +24,12 @@ public: BinaryStream() = default; ~BinaryStream() { - if (m_ptr) - delete m_ptr; m_ptr = m_cur = nullptr; m_size = 0; } - void init(uint8_t* owned_data_ptr, size_t size, ByteOrder byte_order = ByteOrder::Host) + void init(uint8_t* data_ptr, size_t size, ByteOrder byte_order = ByteOrder::Host) { - m_ptr = m_cur = owned_data_ptr; + m_ptr = m_cur = data_ptr; m_size = size; m_byte_order = byte_order; m_swap = byte_order == ByteOrder::Host ? false : byte_order != sys_order(); diff --git a/src/app_vr.cpp b/src/app_vr.cpp index c8276b8..3b8e84f 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -112,6 +112,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset); glActiveTexture(GL_TEXTURE0); diff --git a/src/brush.h b/src/brush.h index ec6e6d2..0d407a5 100644 --- a/src/brush.h +++ b/src/brush.h @@ -52,7 +52,7 @@ public: bool m_tip_flipy = false; bool m_pattern_enabled = false; bool m_dual_enabled = false; - int m_dual_blend_mode = 0; + int m_dual_blend_mode = 1; bool m_dual_randflip = false; float m_dual_size = .25; float m_dual_spacing = .25; @@ -68,7 +68,7 @@ public: float m_dual_opacity = 1.f; float m_dual_rotate = .25f; - int m_pattern_blend_mode = 0; + int m_pattern_blend_mode = 1; bool m_pattern_eachsample = false; bool m_pattern_invert = false; bool m_pattern_flipx = false; diff --git a/src/canvas.cpp b/src/canvas.cpp index c389c32..b83c838 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -500,6 +500,7 @@ void Canvas::stroke_draw() ShaderManager::u_float(kShaderUniform::PatternBright, brush->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, brush->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, brush->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, brush->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, m_pattern_offset); ShaderManager::u_int(kShaderUniform::UsePattern, brush->m_pattern_enabled && brush->m_pattern_eachsample); ShaderManager::u_float(kShaderUniform::MixAlpha, brush->m_tip_mix); @@ -810,6 +811,7 @@ void Canvas::stroke_commit() ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, m_pattern_offset); ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 9770250..86091ae 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -229,6 +229,7 @@ void NodeCanvas::draw() ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset); ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 594653b..09df855 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -95,6 +95,7 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2 ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f)); ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); @@ -302,6 +303,7 @@ void NodeStrokePreview::draw_stroke() ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f)); ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && b->m_pattern_eachsample); ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj); @@ -405,6 +407,7 @@ void NodeStrokePreview::draw_stroke() ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness); ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast); ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth); + ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode); ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f)); ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); diff --git a/src/shader.h b/src/shader.h index 7152994..f87b0b1 100644 --- a/src/shader.h +++ b/src/shader.h @@ -41,6 +41,7 @@ enum class kShaderUniform : uint16_t PatternBright = const_hash("pattern_bright"), PatternContrast = const_hash("pattern_contr"), PatternDepth = const_hash("pattern_depth"), + PatternBlendMode = const_hash("patt_blend_mode"), Colorize = const_hash("colorize"), DualAlpha = const_hash("dual_alpha"), };