diff --git a/resources/shaders/110/silhouette.fs b/resources/shaders/110/silhouette.fs index 09a175baa..919b7dc1a 100644 --- a/resources/shaders/110/silhouette.fs +++ b/resources/shaders/110/silhouette.fs @@ -1,6 +1,6 @@ #version 110 -uniform vec4 u_base_color; +uniform vec3 u_base_color; void main() { - gl_FragColor = u_base_color; + gl_FragColor = vec4(u_base_color, 1.0); } \ No newline at end of file diff --git a/resources/shaders/110/silhouette_composite.fs b/resources/shaders/110/silhouette_composite.fs index 5518980fd..ea2d65145 100644 --- a/resources/shaders/110/silhouette_composite.fs +++ b/resources/shaders/110/silhouette_composite.fs @@ -1,19 +1,34 @@ #version 110 uniform sampler2D u_sampler; uniform mat3 u_convolution_matrix; -uniform vec2 u_viewport_size; - +uniform vec3 u_viewport_size_alpha; +uniform vec3 u_picking_color; varying vec2 tex_coords; vec4 sample(float offsetX, float offsetY) { return texture2D(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + offsetY)); } + +// see https://docs.gl/sl4/sign +// glsl 110 & 120 may not support the sign func +float sign_glsl_110(float value) +{ + if (value > 1e-6) { + return 1.0; + } + else if (value < -1e-6) { + return -1.0; + } + return 0.0; +} + void main() { vec4 pixels[9]; - float deltaWidth = 1.0 / u_viewport_size.x; - float deltaHeight = 1.0 / u_viewport_size.y; + float deltaWidth = 1.0 / u_viewport_size_alpha.x; + float deltaHeight = 1.0 / u_viewport_size_alpha.y; + float alpha = u_viewport_size_alpha.z; float effect_width = 2.0; deltaWidth = deltaWidth * effect_width; deltaHeight = deltaHeight * effect_width; @@ -31,8 +46,12 @@ void main() { for (int j = 0; j < 3; ++j) { - accumulator += pixels[3 * i + j] * u_convolution_matrix[i][j]; + accumulator += sign_glsl_110(pixels[3 * i + j].a) * vec4(u_picking_color, 1.0) * u_convolution_matrix[i][j]; } } + + if ((abs(accumulator.a) - alpha * pixels[4].a) * 1e6 > 1.0) { + accumulator = vec4(u_picking_color, abs(accumulator.a)); + } gl_FragColor = accumulator; } \ No newline at end of file diff --git a/resources/shaders/140/silhouette.fs b/resources/shaders/140/silhouette.fs index 33178205d..1b09200f7 100644 --- a/resources/shaders/140/silhouette.fs +++ b/resources/shaders/140/silhouette.fs @@ -1,8 +1,8 @@ #version 140 -uniform vec4 u_base_color; +uniform vec3 u_base_color; out vec4 frag_color; void main() { - frag_color = u_base_color; + frag_color = vec4(u_base_color, 1.0); } \ No newline at end of file diff --git a/resources/shaders/140/silhouette_composite.fs b/resources/shaders/140/silhouette_composite.fs index 964b2d220..164008bec 100644 --- a/resources/shaders/140/silhouette_composite.fs +++ b/resources/shaders/140/silhouette_composite.fs @@ -1,7 +1,8 @@ #version 140 uniform sampler2D u_sampler; uniform mat3 u_convolution_matrix; -uniform vec2 u_viewport_size; +uniform vec3 u_viewport_size_alpha; +uniform vec3 u_picking_color; in vec2 tex_coords; @@ -14,8 +15,9 @@ vec4 sample(float offsetX, float offsetY) void main() { vec4 pixels[9]; - float deltaWidth = 1.0 / u_viewport_size.x; - float deltaHeight = 1.0 / u_viewport_size.y; + float deltaWidth = 1.0 / u_viewport_size_alpha.x; + float deltaHeight = 1.0 / u_viewport_size_alpha.y; + float alpha = u_viewport_size_alpha.z; float effect_width = 2.0; deltaWidth = deltaWidth * effect_width; deltaHeight = deltaHeight * effect_width; @@ -34,8 +36,12 @@ void main() { for (int j = 0; j < 3; ++j) { - accumulator += pixels[3 * i + j] * u_convolution_matrix[i][j]; + accumulator += sign(pixels[3 * i + j].a) * vec4(u_picking_color, 1.0) * u_convolution_matrix[i][j]; } } + + if ((abs(accumulator.a) - alpha * pixels[4].a) * 1e6 > 1.0) { + accumulator = vec4(u_picking_color, abs(accumulator.a)); + } frag_color = accumulator; } \ No newline at end of file diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b4d3c2bbb..196cda1ce 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2162,6 +2162,18 @@ void GLCanvas3D::render(bool only_init) } wxGetApp().set_picking_effect(EPickingEffect::Silhouette); + ColorRGB picking_color; + if (m_canvas_type == ECanvasType::CanvasAssembleView) { + picking_color.set(0, 1.0f); + picking_color.set(1, 1.0f); + picking_color.set(2, 0.0f); + } + else { + picking_color.set(0, 1.0f); + picking_color.set(1, 1.0f); + picking_color.set(2, 1.0f); + } + wxGetApp().set_picking_color(picking_color); if (only_init) return; @@ -9849,19 +9861,7 @@ void GLCanvas3D::_render_silhouette_effect() wxGetApp().bind_shader(p_silhouette_shader); - std::array picking_color{ 1.0f, 0.36f, 0.0f, 1.0f }; - if (m_canvas_type == ECanvasType::CanvasAssembleView) { - picking_color[0] = 1.0f; - picking_color[1] = 1.0f; - picking_color[2] = 0.0f; - picking_color[3] = 1.0f; - } - else { - picking_color[0] = 1.0f; - picking_color[1] = 1.0f; - picking_color[2] = 1.0f; - picking_color[3] = 1.0f; - } + const auto& picking_color = wxGetApp().get_picking_color(); p_silhouette_shader->set_uniform("u_base_color", picking_color); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -9979,23 +9979,28 @@ void GLCanvas3D::_composite_silhouette_effect() uint32_t viewport_width = 0; uint32_t viewport_height = 0; p_ogl_manager->get_viewport_size(viewport_width, viewport_height); - const std::array viewport_size{ static_cast(viewport_width), static_cast(viewport_height) }; - p_silhouette_composite_shader->set_uniform("u_viewport_size", viewport_size); + const float alpha = 0.4f; Matrix3f convolution_matrix; - convolution_matrix.data()[3 * 0 + 0] = -0.4f; - convolution_matrix.data()[3 * 0 + 1] = -0.4f; - convolution_matrix.data()[3 * 0 + 2] = -0.4f; + convolution_matrix.data()[3 * 0 + 0] = -alpha; + convolution_matrix.data()[3 * 0 + 1] = -alpha; + convolution_matrix.data()[3 * 0 + 2] = -alpha; - convolution_matrix.data()[3 * 1 + 0] = -0.4f; - convolution_matrix.data()[3 * 1 + 1] = 3.6f; - convolution_matrix.data()[3 * 1 + 2] = -0.4f; + convolution_matrix.data()[3 * 1 + 0] = -alpha; + convolution_matrix.data()[3 * 1 + 1] = alpha * 9.0f; + convolution_matrix.data()[3 * 1 + 2] = -alpha; - convolution_matrix.data()[3 * 2 + 0] = -0.4f; - convolution_matrix.data()[3 * 2 + 1] = -0.4f; - convolution_matrix.data()[3 * 2 + 2] = -0.4f; + convolution_matrix.data()[3 * 2 + 0] = -alpha; + convolution_matrix.data()[3 * 2 + 1] = -alpha; + convolution_matrix.data()[3 * 2 + 2] = -alpha; p_silhouette_composite_shader->set_uniform("u_convolution_matrix", convolution_matrix); + const std::array viewport_size_alpha{ static_cast(viewport_width), static_cast(viewport_height), alpha }; + p_silhouette_composite_shader->set_uniform("u_viewport_size_alpha", viewport_size_alpha); + + const auto& picking_color = wxGetApp().get_picking_color(); + p_silhouette_composite_shader->set_uniform("u_picking_color", picking_color); + const int stage = 0; p_silhouette_composite_shader->set_uniform("u_sampler", stage); glsafe(::glActiveTexture(GL_TEXTURE0 + stage)); diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index c9ebc331b..a0c16b061 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -4,6 +4,7 @@ #include "3DScene.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/format.hpp" +#include "libslic3r/Color.hpp" #include #include @@ -372,6 +373,16 @@ bool GLShaderProgram::set_uniform(const char* name, const Vec3d& value) const return set_uniform(name, static_cast(value.cast())); } +bool GLShaderProgram::set_uniform(const char* name, const ColorRGB& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform3fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + int GLShaderProgram::get_attrib_location(const char* name) const { assert(m_id > 0); diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index c412d16d1..d48eba899 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -8,6 +8,7 @@ #include "libslic3r/Point.hpp" namespace Slic3r { +class ColorRGB; class GLShaderProgram { @@ -61,6 +62,7 @@ public: bool set_uniform(const char* name, const Matrix4d& value) const; bool set_uniform(const char* name, const Vec3f& value) const; bool set_uniform(const char* name, const Vec3d& value) const; + bool set_uniform(const char* name, const ColorRGB& value) const; // returns -1 if not found int get_attrib_location(const char* name) const; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7713ea16c..4f7f8ef37 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -7325,6 +7325,16 @@ EPickingEffect GUI_App::get_picking_effect() const return m_picking_effect; } +void GUI_App::set_picking_color(const ColorRGB& color) +{ + m_picking_color = color; +} + +const ColorRGB& GUI_App::get_picking_color() const +{ + return m_picking_color; +} + bool GUI_App::open_browser_with_warning_dialog(const wxString& url, int flags/* = 0*/) { return wxLaunchDefaultBrowser(url, flags); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index e30952ba2..ef498d1d7 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -668,6 +668,9 @@ public: void set_picking_effect(EPickingEffect effect); EPickingEffect get_picking_effect() const; + void set_picking_color(const ColorRGB& color); + const ColorRGB& get_picking_color() const; + private: int updating_bambu_networking(); bool on_init_inner(); @@ -697,6 +700,7 @@ private: boost::optional m_last_config_version; std::string m_open_method; EPickingEffect m_picking_effect{ EPickingEffect::StencilOutline }; + ColorRGB m_picking_color{ 1.0f, 1.0f, 1.0f }; }; DECLARE_APP(GUI_App)