diff --git a/resources/shaders/110/phong.fs b/resources/shaders/110/phong.fs index f2d1c405906..a0c6372ca5e 100644 --- a/resources/shaders/110/phong.fs +++ b/resources/shaders/110/phong.fs @@ -10,18 +10,18 @@ const float EPSILON = 0.0001; // normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) 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.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 128.0 +#define LIGHT_TOP_DIFFUSE (0.85 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.35 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 32.0 // normalized values for (1./1.43, 0.2/1.43, 1./1.43) 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.28 * INTENSITY_CORRECTION) -#define LIGHT_FRONT_SHININESS 64.0 +#define LIGHT_FRONT_DIFFUSE (0.35 * INTENSITY_CORRECTION) +#define LIGHT_FRONT_SPECULAR (0.12 * INTENSITY_CORRECTION) +#define LIGHT_FRONT_SHININESS 16.0 -#define INTENSITY_AMBIENT 0.22 -#define WINDOW_REFLECTION_INTENSITY 0.55 +#define INTENSITY_AMBIENT 0.25 +#define WINDOW_REFLECTION_INTENSITY 0.30 struct PrintVolumeDetection { @@ -162,11 +162,11 @@ vec3 compute_window_reflection(vec3 normal, vec3 view_dir) float bars = 1.0; // Fresnel effect for edge glow - float fresnel = pow(1.0 - max(dot(normal, view_dir), 0.0), 1.0); + float fresnel = pow(1.0 - max(dot(normal, view_dir), 0.0), 1.2); float facing = smoothstep(-0.4, 0.6, reflect_light.z); - float intensity = window_light * bars * (0.25 + 0.25 * fresnel) * facing; - intensity = clamp(intensity, 0.0, 0.45); + float intensity = window_light * bars * (0.15 + 0.15 * fresnel) * facing; + intensity = clamp(intensity, 0.0, 0.25); return vec3(intensity); } diff --git a/resources/shaders/140/phong.fs b/resources/shaders/140/phong.fs index a8cc501b49d..d7456663ec1 100644 --- a/resources/shaders/140/phong.fs +++ b/resources/shaders/140/phong.fs @@ -10,18 +10,18 @@ const float EPSILON = 0.0001; // normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) 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.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 128.0 +#define LIGHT_TOP_DIFFUSE (0.85 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.35 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 32.0 // normalized values for (1./1.43, 0.2/1.43, 1./1.43) 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.28 * INTENSITY_CORRECTION) -#define LIGHT_FRONT_SHININESS 64.0 +#define LIGHT_FRONT_DIFFUSE (0.35 * INTENSITY_CORRECTION) +#define LIGHT_FRONT_SPECULAR (0.12 * INTENSITY_CORRECTION) +#define LIGHT_FRONT_SHININESS 16.0 -#define INTENSITY_AMBIENT 0.22 -#define WINDOW_REFLECTION_INTENSITY 0.55 +#define INTENSITY_AMBIENT 0.25 +#define WINDOW_REFLECTION_INTENSITY 0.30 struct PrintVolumeDetection { @@ -164,12 +164,13 @@ vec3 compute_window_reflection(vec3 normal, vec3 view_dir) // No bars - just pure circular glass float bars = 1.0; - // Fresnel effect for edge glow - float fresnel = pow(1.0 - max(dot(normal, view_dir), 0.0), 1.0); + + float fresnel = pow(1.0 - max(dot(normal, view_dir), 0.0), 1.2); float facing = smoothstep(-0.4, 0.6, reflect_light.z); - float intensity = window_light * bars * (0.25 + 0.25 * fresnel) * facing; - intensity = clamp(intensity, 0.0, 0.45); + + float intensity = window_light * bars * (0.15 + 0.15 * fresnel) * facing; + intensity = clamp(intensity, 0.0, 0.25); return vec3(intensity); } diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index e9f73d2c1e5..e84f469670b 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -276,6 +276,9 @@ void AppConfig::set_defaults() if (get(SETTING_OPENGL_PHONG_BASIC_PLATE_SHADOWS).empty()) set_bool(SETTING_OPENGL_PHONG_BASIC_PLATE_SHADOWS, false); + if (get(SETTING_OPENGL_PHONG_SMOOTH_NORMALS).empty()) + set_bool(SETTING_OPENGL_PHONG_SMOOTH_NORMALS, false); + if (get(SETTING_OPENGL_PHONG_SSAO).empty()) set_bool(SETTING_OPENGL_PHONG_SSAO, false); diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp index 686843f5480..2c83ebb4883 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -39,6 +39,7 @@ using namespace nlohmann; #define SETTING_OPENGL_SHADING_MODEL "opengl_shading_model" #define SETTING_OPENGL_PHONG_BASIC_PLATE_SHADOWS "opengl_phong_basic_plate_shadows" #define SETTING_OPENGL_PHONG_SSAO "opengl_phong_ssao" +#define SETTING_OPENGL_PHONG_SMOOTH_NORMALS "opengl_phong_smooth_normals" #if defined(_WIN32) || defined(_WIN64) #define BAMBU_NETWORK_AGENT_VERSION_LEGACY "01.10.01.09" diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a1078cdb483..06ebbbf41d7 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -24,8 +24,7 @@ // Enable rendering of objects using environment map #define ENABLE_ENVIRONMENT_MAP 0 -// Enable smoothing of objects normals -#define ENABLE_SMOOTH_NORMALS 0 + // Enable rendering markers for options in preview as fixed screen size points #define ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS 1 diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 6cccb87c2f0..ec7deeb82a4 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -758,13 +758,9 @@ int GLVolumeCollection::load_object_volume( GLVolume& v = *this->volumes.back(); v.set_color(color_from_model_volume(*model_volume)); v.name = model_volume->name; - -#if ENABLE_SMOOTH_NORMALS - v.model.init_from(mesh, true); -#else + v.model.init_from(*mesh); if (need_raycaster) { v.mesh_raycaster = std::make_unique(mesh); } -#endif // ENABLE_SMOOTH_NORMALS v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); if (model_volume->is_model_part()) @@ -815,13 +811,9 @@ void GLVolumeCollection::load_object_auxiliary( const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; this->volumes.emplace_back(new GLVolume((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR)); GLVolume& v = *this->volumes.back(); -#if ENABLE_SMOOTH_NORMALS - v.model.init_from(mesh, true); -#else v.model.init_from(mesh); v.model.set_color((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR); v.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_SMOOTH_NORMALS v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first); v.geometry_id = std::pair(timestamp, model_instance.id().id); // Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e9cc99ecb24..5bfdea07dc8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2793,22 +2793,14 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles); assert(! mesh.empty()); mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse()); -#if ENABLE_SMOOTH_NORMALS - volume.model.init_from(mesh, true); -#else volume.model.init_from(mesh); volume.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_SMOOTH_NORMALS } else { // Reload the original volume. -#if ENABLE_SMOOTH_NORMALS - volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true); -#else const TriangleMesh& new_mesh = m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(); volume.model.init_from(new_mesh); volume.mesh_raycaster = std::make_unique(std::make_shared(new_mesh)); -#endif // ENABLE_SMOOTH_NORMALS } } //FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable @@ -10001,11 +9993,7 @@ void GLCanvas3D::_load_sla_shells() const TriangleMesh& mesh, const ColorRGBA& color, bool outside_printer_detection_enabled) { m_volumes.volumes.emplace_back(new GLVolume(color)); GLVolume& v = *m_volumes.volumes.back(); -#if ENABLE_SMOOTH_NORMALS - v.model.init_from(mesh, true); -#else v.model.init_from(mesh); -#endif // ENABLE_SMOOTH_NORMALS v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled; v.composite_id.volume_id = volume_id; v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0)); diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 97a34dca854..f7fab438172 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -14,18 +14,20 @@ #include #include -#if ENABLE_SMOOTH_NORMALS +#if defined(L) +#undef L +#endif + #include #include #include -#endif // ENABLE_SMOOTH_NORMALS + #include namespace Slic3r { namespace GUI { -#if ENABLE_SMOOTH_NORMALS static void smooth_normals_corner(const TriangleMesh& mesh, std::vector& normals) { using MapMatrixXfUnaligned = Eigen::Map>; @@ -41,7 +43,7 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vector(); Eigen::MatrixXd out_normals; - igl::per_corner_normals(vertices, indices, in_normals, 1.0, out_normals); + igl::per_corner_normals(vertices, indices, 1.0, out_normals); normals = std::vector(mesh.its.vertices.size()); for (size_t i = 0; i < mesh.its.indices.size(); ++i) { @@ -50,7 +52,6 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vectorget_bool(SETTING_OPENGL_REALISTIC_MODE); + const bool smooth_normals_enabled = wxGetApp().app_config != nullptr && wxGetApp().app_config->get_bool(SETTING_OPENGL_PHONG_SMOOTH_NORMALS); + + if (realistic_mode && smooth_normals_enabled) { + // Use per-corner smooth normals (via IGL) + using MapMatrixXfUnaligned = Eigen::Map>; + using MapMatrixXiUnaligned = Eigen::Map>; + Eigen::MatrixXd vertices = MapMatrixXfUnaligned(its.vertices.front().data(), Eigen::Index(its.vertices.size()), 3).cast(); + Eigen::MatrixXi indices = MapMatrixXiUnaligned(its.indices.front().data(), Eigen::Index(its.indices.size()), 3); + Eigen::MatrixXd corner_normals; + igl::per_corner_normals(vertices, indices, 5.0, corner_normals); + + unsigned int vertices_counter = 0; + for (uint32_t i = 0; i < its.indices.size(); ++i) { + const stl_triangle_vertex_indices face = its.indices[i]; + for (size_t j = 0; j < 3; ++j) { + const Vec3f normal = corner_normals.row(Eigen::Index(i * 3 + j)).cast(); + data.add_vertex(its.vertices[face[j]], normal); + } + data.add_triangle(vertices_counter, vertices_counter + 1, vertices_counter + 2); + vertices_counter += 3; + } + } else { + //Original flat (per-face) normals + unsigned int vertices_counter = 0; + for (uint32_t i = 0; i < its.indices.size(); ++i) { + const stl_triangle_vertex_indices face = its.indices[i]; + const stl_vertex vertex[3] = {its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]]}; + const stl_vertex n = face_normal_normalized(vertex); + for (size_t j = 0; j < 3; ++j) + data.add_vertex(vertex[j], n); + data.add_triangle(vertices_counter, vertices_counter + 1, vertices_counter + 2); + vertices_counter += 3; } - vertices_counter += 3; - data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } // update bounding box diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index ef3d8fcee52..0292c5f78a7 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1578,6 +1578,15 @@ void PreferencesDialog::create_items() ); g_sizer->Add(item_realistic_shadows); + + auto item_realistic_smooth_normals = create_item_checkbox( + _L("Smooth normals"), + _L("Applies smooth normals to the realistic view.\n\nRequires manual scene reload to take effect " + "(right-click on 3D view → \"Reload All\")."), + SETTING_OPENGL_PHONG_SMOOTH_NORMALS + ); + g_sizer->Add(item_realistic_smooth_normals); + //// GRAPHICS > Anti-aliasing g_sizer->Add(create_item_title(_L("Anti-aliasing")), 1, wxEXPAND);