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