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

View File

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

View File

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

View File

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

View File

@ -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<float, 4> 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<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;
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<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;
p_silhouette_composite_shader->set_uniform("u_sampler", stage);
glsafe(::glActiveTexture(GL_TEXTURE0 + stage));

View File

@ -4,6 +4,7 @@
#include "3DScene.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/format.hpp"
#include "libslic3r/Color.hpp"
#include <boost/nowide/fstream.hpp>
#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>()));
}
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
{
assert(m_id > 0);

View File

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

View File

@ -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);

View File

@ -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<Semver> 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)