diff --git a/data/layout.xml b/data/layout.xml
index 7ee3710..2147222 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -801,7 +801,7 @@
-->
-
+
diff --git a/engine/app_shaders.cpp b/engine/app_shaders.cpp
index 3e2348c..146898d 100644
--- a/engine/app_shaders.cpp
+++ b/engine/app_shaders.cpp
@@ -348,16 +348,23 @@ void App::initShaders()
#else
" mediump vec4 bg = texture(tex_bg, uv2);\n"
#endif
- " mediump vec4 mbg = texture(tex_mix, uv_2);\n"
- " bg.rgb = mix(bg.rgb, mbg.rgb, mix_alpha);\n"
" fg.a *= 1.0-rand(uv2+uv)*noise;\n"
" if (fg.a == 0.0) discard;\n"
+ " if (mix_alpha > 0.0){\n"
+ " mediump vec2 uv_mix = uv_2 / q;\n"
+ " if (uv_mix.x < 0.0 || uv_mix.x > 1.0 || uv_mix.y < 0.0 || uv_mix.y > 1.0) discard;\n"
+ " mediump vec4 mbg = texture(tex_mix, uv_mix);\n"
+ " fg.rgb = mix(fg.rgb, mbg.rgb, mix_alpha);\n"
+ " }\n"
" mediump float contribution = (1.0 - bg.a) * fg.a;\n"
" mediump float alpha_tot = bg.a + contribution;"
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
" mediump vec4 frag_wet = vec4(rgb, max(bg.a, fg.a * 1.2));\n"
" mediump vec4 frag_dry = vec4(rgb, alpha_tot);\n"
" frag = mix(frag_dry, frag_wet, wet);\n"
+
+// " mediump vec4 mbg = texture(tex_mix, uv_2 / q);\n"
+// " frag.rgb = mix(frag.rgb, mbg.rgb, mix_alpha);\n"
"}\n";
static const char* shader_checkerboard_v =
diff --git a/engine/canvas.cpp b/engine/canvas.cpp
index a33e8b3..20af869 100644
--- a/engine/canvas.cpp
+++ b/engine/canvas.cpp
@@ -346,12 +346,28 @@ void ui::Canvas::stroke_draw()
static glm::vec2 UV2[4];
int intersected = 0;
int inside = 0;
+ if (m_mixer_idle)
+ {
+ m_mixer_sample = s;
+ m_mixer_idle = false;
+ }
for (int j = 0; j < 4; j++)
{
glm::vec3 ray_origin, ray_dir;
point_unproject(s.pos + off[j] * glm::orientate2(-s.angle), { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
- UV2[j] = (s.pos + off[j]) / glm::vec2(m_mixer.getWidth(), m_mixer.getHeight());
- UV2[j].y = 1 - UV2[j].y;
+
+ {
+ glm::vec2 dx(m_mixer_sample.size * 0.5f, 0), dy(0, m_mixer_sample.size * 0.5f);
+ glm::vec2 off[4] = {
+ -dx - dy, // A - bottom-left
+ -dx + dy, // B - top-left
+ +dx + dy, // C - top-right
+ +dx - dy, // D - bottom-right
+ };
+ UV2[j] = (m_mixer_sample.pos + off[j]) / glm::vec2(m_mixer.getWidth(), m_mixer.getHeight());
+ UV2[j].y = 1 - UV2[j].y;
+ }
+
glm::vec3 hit;
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i], hit))
{
@@ -373,6 +389,8 @@ void ui::Canvas::stroke_draw()
}
}
+ m_mixer_sample = s;
+
if (intersected < 4 || inside == 0)
continue;
@@ -521,6 +539,7 @@ void ui::Canvas::stroke_commit()
if (!m_dirty || m_layers.empty())
return;
+ m_mixer_idle = true;
m_dirty = false;
m_dirty_stroke = true; // new stroke ready for timelapse capture
App::I.redraw = true;
diff --git a/engine/canvas.h b/engine/canvas.h
index bd3b67e..18edf14 100644
--- a/engine/canvas.h
+++ b/engine/canvas.h
@@ -76,6 +76,8 @@ public:
bool m_smask_active = false;
RTT m_tmp[6];
RTT m_mixer;
+ ui::StrokeSample m_mixer_sample;
+ bool m_mixer_idle = true;
Texture2D m_brush_mix;
Texture2D m_tex[6];
Texture2D m_tex2[6];
diff --git a/engine/shape.cpp b/engine/shape.cpp
index b7c1c99..e1a3228 100644
--- a/engine/shape.cpp
+++ b/engine/shape.cpp
@@ -236,6 +236,7 @@ void ui::Plane::update_vertices(const glm::vec4* data, const glm::vec2* uvs, con
if (uvs2)
vertices[i].uvs2 = uvs2[i];
vertices[i].uvs *= q;
+ vertices[i].uvs2 *= q;
vertices[i].pos.z = q;
}