ENH: remove black edge of silhouette effect

jira: no-jira

Change-Id: Id1b2e6f78bb567ebc74cf5a20c77fd9f5337f044
This commit is contained in:
jun.zhang 2025-03-24 12:12:34 +08:00 committed by lane.wei
parent 26f107dbe8
commit 2589673749
9 changed files with 94 additions and 37 deletions

View File

@ -1,6 +1,6 @@
#version 110 #version 110
uniform vec4 u_base_color; uniform vec3 u_base_color;
void main() void main()
{ {
gl_FragColor = u_base_color; gl_FragColor = vec4(u_base_color, 1.0);
} }

View File

@ -1,19 +1,34 @@
#version 110 #version 110
uniform sampler2D u_sampler; uniform sampler2D u_sampler;
uniform mat3 u_convolution_matrix; 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; varying vec2 tex_coords;
vec4 sample(float offsetX, float offsetY) vec4 sample(float offsetX, float offsetY)
{ {
return texture2D(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + 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() void main()
{ {
vec4 pixels[9]; vec4 pixels[9];
float deltaWidth = 1.0 / u_viewport_size.x; float deltaWidth = 1.0 / u_viewport_size_alpha.x;
float deltaHeight = 1.0 / u_viewport_size.y; float deltaHeight = 1.0 / u_viewport_size_alpha.y;
float alpha = u_viewport_size_alpha.z;
float effect_width = 2.0; float effect_width = 2.0;
deltaWidth = deltaWidth * effect_width; deltaWidth = deltaWidth * effect_width;
deltaHeight = deltaHeight * effect_width; deltaHeight = deltaHeight * effect_width;
@ -31,8 +46,12 @@ void main()
{ {
for (int j = 0; j < 3; ++j) 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; gl_FragColor = accumulator;
} }

View File

@ -1,8 +1,8 @@
#version 140 #version 140
uniform vec4 u_base_color; uniform vec3 u_base_color;
out vec4 frag_color; out vec4 frag_color;
void main() void main()
{ {
frag_color = u_base_color; frag_color = vec4(u_base_color, 1.0);
} }

View File

@ -1,7 +1,8 @@
#version 140 #version 140
uniform sampler2D u_sampler; uniform sampler2D u_sampler;
uniform mat3 u_convolution_matrix; 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; in vec2 tex_coords;
@ -14,8 +15,9 @@ vec4 sample(float offsetX, float offsetY)
void main() void main()
{ {
vec4 pixels[9]; vec4 pixels[9];
float deltaWidth = 1.0 / u_viewport_size.x; float deltaWidth = 1.0 / u_viewport_size_alpha.x;
float deltaHeight = 1.0 / u_viewport_size.y; float deltaHeight = 1.0 / u_viewport_size_alpha.y;
float alpha = u_viewport_size_alpha.z;
float effect_width = 2.0; float effect_width = 2.0;
deltaWidth = deltaWidth * effect_width; deltaWidth = deltaWidth * effect_width;
deltaHeight = deltaHeight * effect_width; deltaHeight = deltaHeight * effect_width;
@ -34,8 +36,12 @@ void main()
{ {
for (int j = 0; j < 3; ++j) 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; frag_color = accumulator;
} }

View File

@ -2162,6 +2162,18 @@ void GLCanvas3D::render(bool only_init)
} }
wxGetApp().set_picking_effect(EPickingEffect::Silhouette); 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) if (only_init)
return; return;
@ -9849,19 +9861,7 @@ void GLCanvas3D::_render_silhouette_effect()
wxGetApp().bind_shader(p_silhouette_shader); wxGetApp().bind_shader(p_silhouette_shader);
std::array<float, 4> picking_color{ 1.0f, 0.36f, 0.0f, 1.0f }; const auto& picking_color = wxGetApp().get_picking_color();
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;
}
p_silhouette_shader->set_uniform("u_base_color", picking_color); p_silhouette_shader->set_uniform("u_base_color", picking_color);
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
@ -9979,23 +9979,28 @@ void GLCanvas3D::_composite_silhouette_effect()
uint32_t viewport_width = 0; uint32_t viewport_width = 0;
uint32_t viewport_height = 0; uint32_t viewport_height = 0;
p_ogl_manager->get_viewport_size(viewport_width, viewport_height); p_ogl_manager->get_viewport_size(viewport_width, viewport_height);
const std::array<float, 2> viewport_size{ static_cast<float>(viewport_width), static_cast<float>(viewport_height) };
p_silhouette_composite_shader->set_uniform("u_viewport_size", viewport_size);
const float alpha = 0.4f;
Matrix3f convolution_matrix; Matrix3f convolution_matrix;
convolution_matrix.data()[3 * 0 + 0] = -0.4f; convolution_matrix.data()[3 * 0 + 0] = -alpha;
convolution_matrix.data()[3 * 0 + 1] = -0.4f; convolution_matrix.data()[3 * 0 + 1] = -alpha;
convolution_matrix.data()[3 * 0 + 2] = -0.4f; convolution_matrix.data()[3 * 0 + 2] = -alpha;
convolution_matrix.data()[3 * 1 + 0] = -0.4f; convolution_matrix.data()[3 * 1 + 0] = -alpha;
convolution_matrix.data()[3 * 1 + 1] = 3.6f; convolution_matrix.data()[3 * 1 + 1] = alpha * 9.0f;
convolution_matrix.data()[3 * 1 + 2] = -0.4f; convolution_matrix.data()[3 * 1 + 2] = -alpha;
convolution_matrix.data()[3 * 2 + 0] = -0.4f; convolution_matrix.data()[3 * 2 + 0] = -alpha;
convolution_matrix.data()[3 * 2 + 1] = -0.4f; convolution_matrix.data()[3 * 2 + 1] = -alpha;
convolution_matrix.data()[3 * 2 + 2] = -0.4f; convolution_matrix.data()[3 * 2 + 2] = -alpha;
p_silhouette_composite_shader->set_uniform("u_convolution_matrix", convolution_matrix); p_silhouette_composite_shader->set_uniform("u_convolution_matrix", convolution_matrix);
const std::array<float, 3> viewport_size_alpha{ static_cast<float>(viewport_width), static_cast<float>(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; const int stage = 0;
p_silhouette_composite_shader->set_uniform("u_sampler", stage); p_silhouette_composite_shader->set_uniform("u_sampler", stage);
glsafe(::glActiveTexture(GL_TEXTURE0 + stage)); glsafe(::glActiveTexture(GL_TEXTURE0 + stage));

View File

@ -4,6 +4,7 @@
#include "3DScene.hpp" #include "3DScene.hpp"
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "libslic3r/format.hpp" #include "libslic3r/format.hpp"
#include "libslic3r/Color.hpp"
#include <boost/nowide/fstream.hpp> #include <boost/nowide/fstream.hpp>
#include <GL/glew.h> #include <GL/glew.h>
@ -372,6 +373,16 @@ bool GLShaderProgram::set_uniform(const char* name, const Vec3d& value) const
return set_uniform(name, static_cast<Vec3f>(value.cast<float>())); return set_uniform(name, static_cast<Vec3f>(value.cast<float>()));
} }
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<const GLfloat*>(value.data())));
return true;
}
return false;
}
int GLShaderProgram::get_attrib_location(const char* name) const int GLShaderProgram::get_attrib_location(const char* name) const
{ {
assert(m_id > 0); assert(m_id > 0);

View File

@ -8,6 +8,7 @@
#include "libslic3r/Point.hpp" #include "libslic3r/Point.hpp"
namespace Slic3r { namespace Slic3r {
class ColorRGB;
class GLShaderProgram class GLShaderProgram
{ {
@ -61,6 +62,7 @@ public:
bool set_uniform(const char* name, const Matrix4d& value) const; 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 Vec3f& value) const;
bool set_uniform(const char* name, const Vec3d& 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 // returns -1 if not found
int get_attrib_location(const char* name) const; int get_attrib_location(const char* name) const;

View File

@ -7325,6 +7325,16 @@ EPickingEffect GUI_App::get_picking_effect() const
return m_picking_effect; 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*/) bool GUI_App::open_browser_with_warning_dialog(const wxString& url, int flags/* = 0*/)
{ {
return wxLaunchDefaultBrowser(url, flags); return wxLaunchDefaultBrowser(url, flags);

View File

@ -668,6 +668,9 @@ public:
void set_picking_effect(EPickingEffect effect); void set_picking_effect(EPickingEffect effect);
EPickingEffect get_picking_effect() const; EPickingEffect get_picking_effect() const;
void set_picking_color(const ColorRGB& color);
const ColorRGB& get_picking_color() const;
private: private:
int updating_bambu_networking(); int updating_bambu_networking();
bool on_init_inner(); bool on_init_inner();
@ -697,6 +700,7 @@ private:
boost::optional<Semver> m_last_config_version; boost::optional<Semver> m_last_config_version;
std::string m_open_method; std::string m_open_method;
EPickingEffect m_picking_effect{ EPickingEffect::StencilOutline }; EPickingEffect m_picking_effect{ EPickingEffect::StencilOutline };
ColorRGB m_picking_color{ 1.0f, 1.0f, 1.0f };
}; };
DECLARE_APP(GUI_App) DECLARE_APP(GUI_App)