From 65b5af9561a94d47fb9937b7a0268dcafc6e5217 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 8 Mar 2022 12:48:21 +0100 Subject: [PATCH] Tech ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - Use vertex attributes and matrices in shaders. Shader: variable_layer_height --- .../shaders/variable_layer_height_attr.vs | 60 ++++++++++++++++ src/slic3r/GUI/GLCanvas3D.cpp | 71 +++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 11 ++- src/slic3r/GUI/GLShadersManager.cpp | 4 ++ 4 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 resources/shaders/variable_layer_height_attr.vs diff --git a/resources/shaders/variable_layer_height_attr.vs b/resources/shaders/variable_layer_height_attr.vs new file mode 100644 index 0000000000..40609bd0d9 --- /dev/null +++ b/resources/shaders/variable_layer_height_attr.vs @@ -0,0 +1,60 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SHININESS 5.0 + +#define INTENSITY_AMBIENT 0.3 + +attribute vec3 v_position; +attribute vec3 v_normal; +attribute vec2 v_tex_coord; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; +uniform mat4 volume_world_matrix; +uniform float object_max_z; + +// x = tainted, y = specular; +varying vec2 intensity; + +varying float object_z; + +void main() +{ + // ===================================================== + // NOTE: + // when object_max_z > 0.0 we are rendering the overlay + // when object_max_z == 0.0 we are rendering the volumes + // ===================================================== + + // First transform the normal into camera space and normalize the result. + vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(normal_matrix * v_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular) + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Scaled to widths of the Z texture. + object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z; + + gl_Position = projection_matrix * position; +} diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a056dc1bd9..ac0e1734aa 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -263,28 +263,29 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) GLCanvas3D::LayersEditing::s_overlay_window_width = ImGui::GetWindowSize().x /*+ (float)m_layers_texture.width/4*/; imgui.end(); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + render_active_object_annotations(canvas); + render_profile(canvas); +#else const Rect& bar_rect = get_bar_rect_viewport(canvas); #if ENABLE_GLBEGIN_GLEND_REMOVAL m_profile.dirty = m_profile.old_bar_rect != bar_rect; #endif // ENABLE_GLBEGIN_GLEND_REMOVAL render_active_object_annotations(canvas, bar_rect); -#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - render_profile(canvas); -#else render_profile(bar_rect); -#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES #if ENABLE_GLBEGIN_GLEND_REMOVAL m_profile.old_bar_rect = bar_rect; m_profile.dirty = false; #endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) { const Vec2d mouse_pos = canvas.get_local_mouse_position(); const Rect& rect = get_bar_rect_screen(canvas); - float x = (float)mouse_pos(0); - float y = (float)mouse_pos(1); + float x = (float)mouse_pos.x(); + float y = (float)mouse_pos.y(); float t = rect.get_top(); float b = rect.get_bottom(); @@ -310,6 +311,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) return { w - thickness_bar_width(canvas), 0.0f, w, h }; } +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) { const Size& cnv_size = canvas.get_canvas_size(); @@ -318,6 +320,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); return { (half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom }; } +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES bool GLCanvas3D::LayersEditing::is_initialized() const { @@ -350,9 +353,25 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con return ret; } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas) +#else void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES { +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const Size cnv_size = canvas.get_canvas_size(); + const float cnv_width = (float)cnv_size.get_width(); + const float cnv_height = (float)cnv_size.get_height(); + if (cnv_width == 0.0f || cnv_height == 0.0f) + return; + + const float cnv_inv_width = 1.0f / cnv_width; + + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -363,13 +382,23 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); shader->set_uniform("z_cursor_band_width", band_width); shader->set_uniform("object_max_z", m_object_max_z); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + shader->set_uniform("normal_matrix", (Matrix3d)Eigen::Matrix3d::Identity()); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); // Render the color bar #if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!m_profile.background.is_initialized() || m_profile.old_canvas_width != cnv_width) { + m_profile.old_canvas_width = cnv_width; +#else if (!m_profile.background.is_initialized() || m_profile.dirty) { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_profile.background.reset(); GLModel::Geometry init_data; @@ -378,10 +407,17 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 init_data.reserve_indices(6); // vertices +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const float l = 1.0f - 2.0f * THICKNESS_BAR_WIDTH * cnv_inv_width; + const float r = 1.0f; + const float t = 1.0f; + const float b = -1.0f; +#else const float l = bar_rect.get_left(); const float r = bar_rect.get_right(); const float t = bar_rect.get_top(); const float b = bar_rect.get_bottom(); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f)); init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f)); init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f)); @@ -447,7 +483,11 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) #if ENABLE_GLBEGIN_GLEND_REMOVAL // Baseline +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!m_profile.baseline.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { +#else if (!m_profile.baseline.is_initialized() || m_profile.dirty) { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_profile.baseline.reset(); GLModel::Geometry init_data; @@ -473,7 +513,11 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) m_profile.baseline.init_from(std::move(init_data)); } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!m_profile.profile.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { +#else if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_profile.old_layer_height_profile = m_layer_height_profile; m_profile.profile.reset(); @@ -545,7 +589,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G if (current_shader != nullptr) current_shader->stop_using(); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -559,6 +607,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); shader->set_uniform("z_cursor_band_width", float(this->band_width)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + // Initialize the layer height texture mapping. const GLsizei w = (GLsizei)m_layers_texture.width; const GLsizei h = (GLsizei)m_layers_texture.height; @@ -577,6 +630,12 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); shader->set_uniform("object_max_z", 0.0f); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = camera.get_view_matrix() * glvolume->world_matrix(); + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glvolume->render(); } // Revert back to the previous shader. diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a1dd213162..bafcfa9ba0 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -245,9 +245,15 @@ class GLCanvas3D GLModel baseline; GLModel profile; GLModel background; +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + float old_canvas_width{ 0.0f }; +#else Rect old_bar_rect; +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES std::vector old_layer_height_profile; +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES bool dirty{ false }; +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES }; Profile m_profile; #endif // ENABLE_GLBEGIN_GLEND_REMOVAL @@ -277,7 +283,9 @@ class GLCanvas3D static float get_cursor_z_relative(const GLCanvas3D& canvas); static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); static Rect get_bar_rect_screen(const GLCanvas3D& canvas); +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; } float object_max_z() const { return m_object_max_z; } @@ -287,10 +295,11 @@ class GLCanvas3D private: bool is_initialized() const; void generate_layer_height_texture(); - void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect); #if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + void render_active_object_annotations(const GLCanvas3D& canvas); void render_profile(const GLCanvas3D& canvas); #else + void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect); void render_profile(const Rect& bar_rect); #endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES void update_slicing_parameters(); diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 6dfc9f9366..abc4cd9a6c 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -96,7 +96,11 @@ std::pair GLShadersManager::init() #endif // ENABLE_ENVIRONMENT_MAP ); // used to render variable layers heights in 3d editor +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + valid &= append_shader("variable_layer_height_attr", { "variable_layer_height_attr.vs", "variable_layer_height.fs" }); +#else valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // used to render highlight contour around selected triangles inside the multi-material gizmo #if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" });