GPencil: Reorganize blend shader

Reorganize code and change some functions to mimic other softwares blend modes. Still need more work.
This commit is contained in:
Antonioya
2019-06-13 13:35:12 +02:00
parent e0c98e18f9
commit 6f43541d8c

View File

@@ -33,46 +33,76 @@ float overlay_color(float a, float b)
return rtn; return rtn;
} }
vec4 get_blend_color(int mode, vec4 src_color, vec4 blend_color) vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color)
{ {
vec4 mix_color = blend_color;
vec4 outcolor; vec4 outcolor;
if (mix_color.a == 0) { if (mix_color.a == 0) {
outcolor = src_color; return src_color;
}
else if (mode == MODE_OVERLAY) {
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor.r = overlay_color(src_color.r, mix_color.r);
outcolor.g = overlay_color(src_color.g, mix_color.g);
outcolor.b = overlay_color(src_color.b, mix_color.b);
outcolor.a = src_color.a;
}
else if (mode == MODE_ADD) {
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color + mix_color;
outcolor.a = src_color.a;
}
else if (mode == MODE_SUB) {
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color - mix_color;
outcolor.a = clamp(src_color.a - mix_color.a, 0.0, 1.0);
}
else if (mode == MODE_MULTIPLY) {
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color * mix_color;
outcolor.a = src_color.a;
}
else if (mode == MODE_DIVIDE) {
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color / mix_color;
outcolor.a = src_color.a;
}
else {
outcolor = mix_color;
outcolor.a = src_color.a;
} }
switch(mode)
{
case MODE_REGULAR:
{
/* premult */
src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
outcolor = vec4(mix(src_color.rgb, mix_color.rgb, mix_color.a),
src_color.a);
break;
}
case MODE_OVERLAY:
{
src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor.r = overlay_color(src_color.r, mix_color.r);
outcolor.g = overlay_color(src_color.g, mix_color.g);
outcolor.b = overlay_color(src_color.b, mix_color.b);
outcolor.a = src_color.a;
break;
}
case MODE_ADD:
{
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color + mix_color;
outcolor.a = src_color.a;
break;
}
case MODE_SUB:
{
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color - mix_color;
outcolor.a = clamp(src_color.a - mix_color.a, 0.0, 1.0);
break;
}
case MODE_MULTIPLY:
{
src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color * mix_color;
outcolor.a = src_color.a;
break;
}
case MODE_DIVIDE:
{
mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
outcolor = src_color / mix_color;
outcolor.a = src_color.a;
break;
}
default:
{
outcolor = mix_color;
outcolor.a = src_color.a;
break;
}
}
return clamp(outcolor, 0.0, 1.0); return clamp(outcolor, 0.0, 1.0);
} }
@@ -110,43 +140,27 @@ void main()
vec4 mix_color = texelFetch(blendColor, uv, 0).rgba; vec4 mix_color = texelFetch(blendColor, uv, 0).rgba;
float mix_depth = texelFetch(blendDepth, uv, 0).r; float mix_depth = texelFetch(blendDepth, uv, 0).r;
/* Default mode */ if (stroke_color.a > 0) {
if (mode == MODE_REGULAR) { if (mix_color.a > 0) {
if (stroke_color.a > 0) { /* apply blend mode */
if (mix_color.a > 0) { FragColor = get_blend_color(mode, stroke_color, mix_color);
/* premult */
stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
FragColor = vec4(mix(stroke_color.rgb, mix_color.rgb, mix_color.a), stroke_color.a);
gl_FragDepth = mix_depth;
}
else {
FragColor = stroke_color;
gl_FragDepth = stroke_depth;
}
} }
else { else {
if (clamp_layer == ON) { FragColor = stroke_color;
discard; }
} gl_FragDepth = min(stroke_depth, mix_depth);
else { }
FragColor = mix_color; else {
gl_FragDepth = mix_depth; if (clamp_layer == ON) {
} discard;
}
else {
/* if not using mask, return mix color */
FragColor = mix_color;
gl_FragDepth = mix_depth;
} }
FragColor = tone(FragColor);
return;
} }
/* if not using mask, return mix color */ /* apply tone mapping */
if ((stroke_color.a == 0) && (clamp_layer == OFF)) { FragColor = tone(FragColor);
FragColor = tone(mix_color);
gl_FragDepth = mix_depth;
return;
}
/* apply blend mode */
FragColor = tone(get_blend_color(mode, stroke_color, mix_color));
gl_FragDepth = stroke_depth;
} }