diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index 850d69b08..ed03bfe64 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -4,7 +4,9 @@ const vec3 ZERO = vec3(0.0, 0.0, 0.0); const vec3 GREEN = vec3(0.0, 0.7, 0.0); const vec3 YELLOW = vec3(0.5, 0.7, 0.0); const vec3 RED = vec3(0.7, 0.0, 0.0); +const vec3 WHITE = vec3(1.0, 1.0, 1.0); const float EPSILON = 0.0001; +const float BANDS_WIDTH = 10.0; struct SlopeDetection { @@ -15,6 +17,7 @@ struct SlopeDetection uniform vec4 uniform_color; uniform SlopeDetection slope; +uniform bool sinking; #ifdef ENABLE_ENVIRONMENT_MAP uniform sampler2D environment_tex; @@ -23,27 +26,38 @@ uniform SlopeDetection slope; varying vec3 clipping_planes_dots; -// x = tainted, y = specular; +// x = diffuse, y = specular; varying vec2 intensity; varying vec3 delta_box_min; varying vec3 delta_box_max; +varying vec4 model_pos; +varying float world_pos_z; varying float world_normal_z; varying vec3 eye_normal; +vec3 sinking_color(vec3 color) +{ + return (mod(model_pos.x + model_pos.y + model_pos.z, BANDS_WIDTH) < (0.5 * BANDS_WIDTH)) ? mix(color, ZERO, 0.6666) : color; +} + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) discard; vec3 color = uniform_color.rgb; float alpha = uniform_color.a; - if (slope.actived && world_normal_z < slope.normal_z - EPSILON) { + if (slope.actived && world_normal_z < slope.normal_z - EPSILON) + { color = vec3(0.7, 0.7, 1.0); alpha = 1.0; } // if the fragment is outside the print volume -> use darker color color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; + // if the object is sinking, shade it with inclined bands or white around world z = 0 + if (sinking) + color = (abs(world_pos_z) < 0.05) ? WHITE : sinking_color(color); #ifdef ENABLE_ENVIRONMENT_MAP if (use_environment_tex) gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha); diff --git a/resources/shaders/gouraud.vs b/resources/shaders/gouraud.vs index ed7e3f56b..f2706b386 100644 --- a/resources/shaders/gouraud.vs +++ b/resources/shaders/gouraud.vs @@ -41,7 +41,7 @@ uniform vec2 z_range; // Clipping plane - general orientation. Used by the SLA gizmo. uniform vec4 clipping_plane; -// x = tainted, y = specular; +// x = diffuse, y = specular; varying vec2 intensity; varying vec3 delta_box_min; @@ -49,6 +49,8 @@ varying vec3 delta_box_max; varying vec3 clipping_planes_dots; +varying vec4 model_pos; +varying float world_pos_z; varying float world_normal_z; varying vec3 eye_normal; @@ -69,12 +71,16 @@ void main() NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + model_pos = gl_Vertex; + // Point in homogenous coordinates. + vec4 world_pos = print_box.volume_world_matrix * gl_Vertex; + world_pos_z = world_pos.z; + // compute deltas for out of print volume detection (world coordinates) if (print_box.actived) { - vec3 v = (print_box.volume_world_matrix * gl_Vertex).xyz; - delta_box_min = v - print_box.min; - delta_box_max = v - print_box.max; + delta_box_min = world_pos.xyz - print_box.min; + delta_box_max = world_pos.xyz - print_box.max; } else { @@ -86,8 +92,6 @@ void main() world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0; gl_Position = ftransform(); - // Point in homogenous coordinates. - vec4 world_pos = print_box.volume_world_matrix * gl_Vertex; // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ba62576f2..57ec1e0d9 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -345,9 +345,16 @@ void GLVolume::set_render_color(const float* rgba, unsigned int size) void GLVolume::set_render_color() { - if (force_native_color || force_neutral_color) - { +#if ENABLE_ALLOW_NEGATIVE_Z + bool outside = is_outside || is_below_printbed(); +#endif // ENABLE_ALLOW_NEGATIVE_Z + + if (force_native_color || force_neutral_color) { +#if ENABLE_ALLOW_NEGATIVE_Z + if (outside && shader_outside_printer_detection_enabled) +#else if (is_outside && shader_outside_printer_detection_enabled) +#endif // ENABLE_ALLOW_NEGATIVE_Z set_render_color(OUTSIDE_COLOR, 4); else { if (force_native_color) @@ -362,17 +369,24 @@ void GLVolume::set_render_color() else if (hover == HS_Deselect) set_render_color(HOVER_DESELECT_COLOR, 4); else if (selected) +#if ENABLE_ALLOW_NEGATIVE_Z + set_render_color(outside ? SELECTED_OUTSIDE_COLOR : SELECTED_COLOR, 4); +#else set_render_color(is_outside ? SELECTED_OUTSIDE_COLOR : SELECTED_COLOR, 4); +#endif // ENABLE_ALLOW_NEGATIVE_Z else if (disabled) set_render_color(DISABLED_COLOR, 4); +#if ENABLE_ALLOW_NEGATIVE_Z + else if (outside && shader_outside_printer_detection_enabled) +#else else if (is_outside && shader_outside_printer_detection_enabled) +#endif // ENABLE_ALLOW_NEGATIVE_Z set_render_color(OUTSIDE_COLOR, 4); else set_render_color(color, 4); } - if (!printable) - { + if (!printable) { render_color[0] /= 4; render_color[1] /= 4; render_color[2] /= 4; @@ -504,6 +518,21 @@ void GLVolume::render() const bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); } bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposPad); } +#if ENABLE_ALLOW_NEGATIVE_Z +bool GLVolume::is_sinking() const +{ + if (is_modifier) + return false; + const BoundingBoxf3& box = transformed_convex_hull_bounding_box(); + return box.min(2) < 0.0 && box.max(2) >= 0.0; +} + +bool GLVolume::is_below_printbed() const +{ + return transformed_convex_hull_bounding_box().max(2) < 0.0; +} +#endif // ENABLE_ALLOW_NEGATIVE_Z + std::vector GLVolumeCollection::load_object( const ModelObject *model_object, int obj_idx, @@ -778,6 +807,9 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); +#if ENABLE_ALLOW_NEGATIVE_Z + shader->set_uniform("sinking", volume.first->is_sinking()); +#endif // ENABLE_ALLOW_NEGATIVE_Z volume.first->render(); } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 25c5443cd..2d46a4524 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -453,6 +453,11 @@ public: bool is_sla_support() const; bool is_sla_pad() const; +#if ENABLE_ALLOW_NEGATIVE_Z + bool is_sinking() const; + bool is_below_printbed() const; +#endif // ENABLE_ALLOW_NEGATIVE_Z + // Return an estimate of the memory consumed by this class. size_t cpu_memory_used() const { //FIXME what to do wih m_convex_hull?