all blending modes for pattern and dual brush

This commit is contained in:
2019-02-22 02:26:25 +01:00
parent 39ee7289c5
commit 876c002616
11 changed files with 75 additions and 21 deletions

View File

@@ -31,7 +31,7 @@
<border height="35" color=".5" dir="row" align="center" flood-events="1" pad="0 0 5 0">
<checkbox id="alpha-lock" icon="data/ui/check-lock-transparency.png" width="30" margin="0 5 0 5"/>
<combobox id="blend-mode" width="100" height="30" margin="0 5 0 0" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
<combobox id="blend-mode" width="100" height="30" margin="0 5 0 0" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay"/>
<slider-h id="opacity" value="1" grow="1" width="1" margin="0 5 0 0"/>
</border>
@@ -217,7 +217,7 @@
<node dir="col" align="center" grow="1" width="1">
<!--controls-->
<node height="30" pad="1" width="100%" dir="row" margin="0 0 5 0">
<combobox id="blend-mode" text="Normal" width="100%" height="28" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
<combobox id="blend-mode" text="Normal" width="100%" height="28" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay"/>
</node>
<node height="40" pad="1" width="100%" dir="col">
<slider-h id="tip-flow" height="19" value=".5"/>
@@ -341,10 +341,10 @@
</node>
</node>
<node height="30" width="100%" pad="1" dir="row" margin="0 0 5 0">
<combobox id="pattern-blend-mode" width="100%" height="28" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
<combobox id="pattern-blend-mode" width="100%" height="28" combo-list="Normal,-,Multiply,Subtract,Darken,Overlay,Color Dodge,Linear Burn,Hard Mix,-,Linear Height,Height"/>
</node>
<node height="30" width="100%" pad="1" dir="row" margin="0 0 5 0">
<combobox id="pattern-proj-mode" width="100%" height="28" combo-list="Cube,Screen" default="0"/>
<combobox id="pattern-proj-mode" width="100%" height="28" combo-list="Cube,Screen"/>
</node>
<node align="center" dir="row">
<checkbox id="pattern-eachsample" height="20" width="20"/>
@@ -429,7 +429,7 @@
</node>
</node>
<node height="30" width="100%" pad="1" dir="row" margin="0 0 5 0">
<combobox id="dual-blend-mode" width="100%" height="28" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="1"/>
<combobox id="dual-blend-mode" width="100%" height="28" combo-list="Normal,-,Multiply,Subtract,Darken,Overlay,Color Dodge,Linear Burn,Hard Mix,-,Linear Height,Height"/>
</node>
<node align="center" dir="row">
<checkbox id="dual-randflip" height="20" width="20"/>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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