further progress on better blending

This commit is contained in:
itsmattkc
2019-01-26 23:34:58 +11:00
parent 97a28ab54a
commit 7a436ef51f
20 changed files with 271 additions and 189 deletions
+37
View File
@@ -0,0 +1,37 @@
#version 110
const int BLEND_MODE_ADD = 0;
const int BLEND_MODE_AVERAGE = 1;
const int BLEND_MODE_COLORBURN = 2;
const int BLEND_MODE_COLORDODGE = 3;
const int BLEND_MODE_DARKEN = 4;
const int BLEND_MODE_DIFFERENCE = 5;
const int BLEND_MODE_EXCLUSION = 6;
const int BLEND_MODE_GLOW = 7;
const int BLEND_MODE_HARDLIGHT = 8;
const int BLEND_MODE_HARDMIX = 9;
const int BLEND_MODE_LIGHTEN = 10;
const int BLEND_MODE_LINEARBURN = 11;
const int BLEND_MODE_LINEARDODGE = 12;
const int BLEND_MODE_LINEARLIGHT = 13;
const int BLEND_MODE_MULTIPLY = 14;
const int BLEND_MODE_NEGATION = 15;
const int BLEND_MODE_NORMAL = 16;
const int BLEND_MODE_OVERLAY = 17;
const int BLEND_MODE_PHOENIX = 18;
const int BLEND_MODE_PINLIGHT = 19;
const int BLEND_MODE_REFLECT = 20;
const int BLEND_MODE_SCREEN = 21;
const int BLEND_MODE_SOFTLIGHT = 22;
const int BLEND_MODE_SUBSTRACT = 23;
const int BLEND_MODE_SUBTRACT = 24;
const int BLEND_MODE_VIVIDLIGHT = 25;
uniform sampler2D background;
uniform sampler2D texture;
varying vec2 vTexCoord;
void main(void) {
// gl_FragColor = texture2D(background, vTexCoord);
gl_FragColor = texture2D(texture, vTexCoord);
}
+8
View File
@@ -0,0 +1,8 @@
#version 110
varying vec2 vTexCoord;
void main() {
vTexCoord = gl_MultiTexCoord0.xy;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
+46
View File
@@ -0,0 +1,46 @@
#version 130
uniform sampler2D tex;
uniform bool perspective;
varying vec2 q;
varying vec2 b1;
varying vec2 b2;
varying vec2 b3;
varying vec2 vTexCoord;
float Wedge2D(vec2 v, vec2 w) {
return (v.x*w.y) - (v.y*w.x);
}
void main(void) {
if (perspective) {
gl_FragColor = texture2D(tex, vTexCoord);
} else {
float A = Wedge2D(b2, b3);
float B = Wedge2D(b3, q) - Wedge2D(b1, b2);
float C = Wedge2D(b1, q);
vec2 uv;
// solve for v
if (abs(A) < 0.001) {
uv.y = -C/B;
} else {
float discrim = B*B - 4.0*A*C;
uv.y = 0.5 * (-B + sqrt(discrim)) / A;
}
// solve for u
vec2 denom = b1 + uv.y * b3;
if (abs(denom.x) > abs(denom.y)) {
uv.x = (q.x - b2.x * uv.y) / denom.x;
} else {
uv.x = (q.y - b2.y * uv.y) / denom.y;
}
uv.y = 1.0 - uv.y;
gl_FragColor = texture2D(tex, uv);
}
}
+66
View File
@@ -0,0 +1,66 @@
#version 130
uniform bool perspective;
uniform vec2 p0;
uniform vec2 p1;
uniform vec2 p2;
uniform vec2 p3;
varying vec2 q;
varying vec2 b1;
varying vec2 b2;
varying vec2 b3;
varying vec2 vTexCoord;
void main() {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
if (perspective) {
float m1 = (p3.y - p0.y)/(p3.x - p0.x);
float c1 = p0.y - m1 * p0.x;
float m2 = (p1.y - p2.y)/(p1.x - p2.x);
float c2 = p2.y - m2 * p2.x;
float mid_x = (c2 - c1) / (m1 - m2);
float mid_y = m1 * mid_x + c1;
float d0 = length(vec2(mid_x - p0.x, mid_y - p0.y));
float d1 = length(vec2(p1.x - mid_x, mid_y - p1.y));
float d2 = length(vec2(p3.x - mid_x, p3.y - mid_y));
float d3 = length(vec2(mid_x - p2.x, p2.y - mid_y));
float q;
if (gl_VertexID == 0) {
q = (d1+d3)/d3;
} else if (gl_VertexID == 1) {
q = (d0+d2)/d2;
} else if (gl_VertexID == 2) {
q = (d3+d1)/d1;
} else {
q = (d2+d0)/d0;
}
gl_Position[0] *= q;
gl_Position[1] *= q;
gl_Position[3] = q;
vTexCoord = gl_MultiTexCoord0.xy;
} else {
vec2 pos;
if (gl_VertexID == 0) { // top left
pos = p2;
} else if (gl_VertexID == 1) { // top right
pos = p3;
} else if (gl_VertexID == 2) { // bottom right
pos = p1;
} else if (gl_VertexID == 3) { // bottom left
pos = p0;
}
q = pos - p0;
b1 = p1 - p0;
b2 = p2 - p0;
b3 = p0 - p1 - p2 + p3;
}
}
+5 -5
View File
@@ -8,23 +8,23 @@ CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em)
enable_coords = true;
enable_shader = true;
EffectRow* top_left = add_row(tr("Top Left"));
EffectRow* top_left = add_row(tr("Top Left"));
top_left_x = top_left->add_field(EFFECT_FIELD_DOUBLE, "topleftx");
top_left_y = top_left->add_field(EFFECT_FIELD_DOUBLE, "toplefty");
EffectRow* top_right = add_row(tr("Top Right"));
EffectRow* top_right = add_row(tr("Top Right"));
top_right_x = top_right->add_field(EFFECT_FIELD_DOUBLE, "toprightx");
top_right_y = top_right->add_field(EFFECT_FIELD_DOUBLE, "toprighty");
EffectRow* bottom_left = add_row(tr("Bottom Left"));
EffectRow* bottom_left = add_row(tr("Bottom Left"));
bottom_left_x = bottom_left->add_field(EFFECT_FIELD_DOUBLE, "bottomleftx");
bottom_left_y = bottom_left->add_field(EFFECT_FIELD_DOUBLE, "bottomlefty");
EffectRow* bottom_right = add_row(tr("Bottom Right"));
EffectRow* bottom_right = add_row(tr("Bottom Right"));
bottom_right_x = bottom_right->add_field(EFFECT_FIELD_DOUBLE, "bottomrightx");
bottom_right_y = bottom_right->add_field(EFFECT_FIELD_DOUBLE, "bottomrighty");
perspective = add_row(tr("Perspective"))->add_field(EFFECT_FIELD_BOOL, "perspective");
perspective = add_row(tr("Perspective"))->add_field(EFFECT_FIELD_BOOL, "perspective");
perspective->set_bool_value(true);
top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+46
View File
@@ -0,0 +1,46 @@
#version 110
uniform sampler2D image;
uniform vec2 resolution;
uniform int shadow;
uniform vec3 shadowcolor;
uniform float shadowsoftness;
uniform float shadowopacity;
uniform float shadowdistance;
varying vec2 vTexCoord;
void main(void) {
/*
vec4 master_px = texture2D(image, vTexCoord);
if (shadow == 1) {
vec2 shadow_dist = vec2(shadowdistance)/resolution;
float shadow_opacity = 0.01*shadowopacity;
vec4 shadowed_px = vec4(shadowcolor.r, shadowcolor.g, shadowcolor.b, shadow_opacity*texture2D(image, vTexCoord-shadow_dist).a);
float rad = floor(shadowsoftness);
if (rad > 0.0) {
shadowed_px.a = 0.0;
float divider = (1.0 / pow(rad, 2.0))*shadow_opacity;
for (float x=-rad+0.5;x<=rad;x+=2.0) {
for (float y=-rad+0.5;y<=rad;y+=2.0) {
shadowed_px.a += shadow_opacity*texture2D(image, vTexCoord-shadow_dist+(vec2(x, y)/resolution)).a*divider;
}
}
}
vec4 shadow_blend = (shadowed_px*(1.0-master_px.a));
vec4 composition = mix(shadow_blend, master_px, master_px.a);
gl_FragColor = composition;
} else {
gl_FragColor = master_px;
}
*/
gl_FragColor = texture2D(image, vTexCoord);
}
+10
View File
@@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/internalshaders">
<file>blending.frag</file>
<file>common.vert</file>
<file>cornerpin.frag</file>
<file>cornerpin.vert</file>
<file>premultiply.frag</file>
<file>dropshadow.frag</file>
</qresource>
</RCC>
+10
View File
@@ -0,0 +1,10 @@
#version 110
uniform sampler2D tex;
varying vec2 vTexCoord;
void main(void) {
vec4 c = texture2D(tex, vTexCoord);
c.rgb *= c.a;
gl_FragColor = c;
}
+66 -65
View File
@@ -94,67 +94,67 @@ TextEffect::TextEffect(Clip *c, const EffectMeta* em) :
}
void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = false) {
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
int r1 = rect.top();
int r2 = rect.bottom();
int c1 = rect.left();
int c2 = rect.right();
int r1 = rect.top();
int r2 = rect.bottom();
int c1 = rect.left();
int c2 = rect.right();
int bpl = result.bytesPerLine();
int rgba[4];
unsigned char* p;
int bpl = result.bytesPerLine();
int rgba[4];
unsigned char* p;
int i1 = 0;
int i2 = 3;
int i1 = 0;
int i2 = 3;
if (alphaOnly)
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
if (alphaOnly)
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r1) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r1) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c1 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c1 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += 4;
for (int j = c1; j < c2; j++, p += 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
p += 4;
for (int j = c1; j < c2; j++, p += 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r2) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r2) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c2 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c2 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}
}
void TextEffect::redraw(double timecode) {
@@ -254,25 +254,25 @@ void TextEffect::redraw(double timecode) {
path.addText(text_x, text_y, font, lines.at(i));
}
// draw software shadow
if (!enable_shader && shadow_bool->get_bool_value(timecode)) {
p.setPen(Qt::NoPen);
int shadow_offset = shadow_distance->get_double_value(timecode);
// draw software shadow
if (shadow_bool->get_bool_value(timecode)) {
p.setPen(Qt::NoPen);
int shadow_offset = shadow_distance->get_double_value(timecode);
QPainterPath shadow_path(path);
shadow_path.translate(shadow_offset, shadow_offset);
QPainterPath shadow_path(path);
shadow_path.translate(shadow_offset, shadow_offset);
QColor col = shadow_color->get_color_value(timecode);
col.setAlpha(0);
img.fill(col);
QColor col = shadow_color->get_color_value(timecode);
col.setAlpha(0);
img.fill(col);
col.setAlphaF(shadow_opacity->get_double_value(timecode)*0.01);
p.setBrush(col);
p.drawPath(shadow_path);
col.setAlphaF(shadow_opacity->get_double_value(timecode)*0.01);
p.setBrush(col);
p.drawPath(shadow_path);
int blurSoftness = shadow_softness->get_double_value(timecode);
if (blurSoftness > 0) blurred2(img, img.rect(), blurSoftness, false);
}
int blurSoftness = shadow_softness->get_double_value(timecode);
if (blurSoftness > 0) blurred2(img, img.rect(), blurSoftness, false);
}
// draw outline
int outline_width_val = outline_width->get_double_value(timecode);
@@ -288,10 +288,11 @@ void TextEffect::redraw(double timecode) {
p.setPen(Qt::NoPen);
p.setBrush(set_color_button->get_color_value(timecode));
p.drawPath(path);
p.end();
}
void TextEffect::shadow_enable(bool e) {
enable_shader = (e && !config.use_software_fallback);
close();
shadow_color->set_enabled(e);