diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index c7c18bb8a..253bb5bda 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -3276,7 +3276,12 @@ bool GLCanvas3D::Gizmos::generate_icons_texture() const
         }
     }
 
-    bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, GLGizmoBase::Num_States, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
+    std::vector<std::pair<int, bool>> states;
+    states.push_back(std::make_pair(1, false));
+    states.push_back(std::make_pair(0, false));
+    states.push_back(std::make_pair(0, true));
+
+    bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
     if (res)
         m_icons_texture_dirty = false;
 
@@ -3713,7 +3718,11 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
 #endif
     , m_in_render(false)
     , m_bed(nullptr)
+#if ENABLE_SVG_ICONS
+    , m_toolbar(GLToolbar::Normal, "Top")
+#else
     , m_toolbar(GLToolbar::Normal)
+#endif // ENABLE_SVG_ICONS
     , m_view_toolbar(nullptr)
     , m_use_clipping_planes(false)
     , m_sidebar_field("")
@@ -5988,7 +5997,7 @@ bool GLCanvas3D::_init_toolbar()
     item.icon_filename = "split_parts.svg";
 #endif // ENABLE_SVG_ICONS
     item.tooltip = GUI::L_str("Split to parts");
-    item.sprite_id = 8;
+    item.sprite_id = 7;
     item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES;
     if (!m_toolbar.add_item(item))
         return false;
@@ -6001,7 +6010,7 @@ bool GLCanvas3D::_init_toolbar()
     item.icon_filename = "layers.svg";
 #endif // ENABLE_SVG_ICONS
     item.tooltip = GUI::L_str("Layers editing");
-    item.sprite_id = 7;
+    item.sprite_id = 8;
     item.is_toggable = true;
     item.action_event = EVT_GLTOOLBAR_LAYERSEDITING;
     if (!m_toolbar.add_item(item))
diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp
index 7e822a4c1..2f1b68048 100644
--- a/src/slic3r/GUI/GLTexture.cpp
+++ b/src/slic3r/GUI/GLTexture.cpp
@@ -138,19 +138,19 @@ bool GLTexture::load_from_file(const std::string& filename, bool use_mipmaps)
 #endif // ENABLE_TEXTURES_FROM_SVG
 
 #if ENABLE_SVG_ICONS
-bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, unsigned int num_states, unsigned int sprite_size_px)
+bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, const std::vector<std::pair<int, bool>>& states, unsigned int sprite_size_px)
 {
-    static int pass = 0;
-    ++pass;
-
     reset();
 
-    if (filenames.empty() || (num_states == 0) || (sprite_size_px == 0))
+    if (filenames.empty() || states.empty() || (sprite_size_px == 0))
         return false;
 
-    m_width = (int)(sprite_size_px * num_states);
+    m_width = (int)(sprite_size_px * states.size());
     m_height = (int)(sprite_size_px * filenames.size());
     int n_pixels = m_width * m_height;
+    int sprite_n_pixels = sprite_size_px * sprite_size_px;
+    int sprite_bytes = sprite_n_pixels * 4;
+    int sprite_stride = sprite_size_px * 4;
 
     if (n_pixels <= 0)
     {
@@ -159,7 +159,10 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
     }
 
     std::vector<unsigned char> data(n_pixels * 4, 0);
-    std::vector<unsigned char> sprite_data(sprite_size_px * sprite_size_px * 4, 0);
+    std::vector<unsigned char> sprite_data(sprite_bytes, 0);
+    std::vector<unsigned char> sprite_white_only_data(sprite_bytes, 0);
+    std::vector<unsigned char> sprite_gray_only_data(sprite_bytes, 0);
+    std::vector<unsigned char> output_data(sprite_bytes, 0);
 
     NSVGrasterizer* rast = nsvgCreateRasterizer();
     if (rast == nullptr)
@@ -185,16 +188,58 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
 
         float scale = (float)sprite_size_px / std::max(image->width, image->height);
 
-        nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_size_px * 4);
+        nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_stride);
+
+        // makes white only copy of the sprite
+        ::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
+        for (int i = 0; i < sprite_n_pixels; ++i)
+        {
+            if (sprite_white_only_data.data()[i * 4] != 0)
+                ::memset((void*)&sprite_white_only_data.data()[i * 4], 255, 3);
+        }
+
+        // makes gray only copy of the sprite
+        ::memcpy((void*)sprite_gray_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
+        for (int i = 0; i < sprite_n_pixels; ++i)
+        {
+            if (sprite_gray_only_data.data()[i * 4] != 0)
+                ::memset((void*)&sprite_gray_only_data.data()[i * 4], 128, 3);
+        }
 
         int sprite_offset_px = sprite_id * sprite_size_px * m_width;
-        for (unsigned int i = 0; i < num_states; ++i)
+        int state_id = -1;
+        for (const std::pair<int, bool>& state : states)
         {
-            int state_offset_px = sprite_offset_px + i * sprite_size_px;
+            ++state_id;
+
+            // select the sprite variant
+            std::vector<unsigned char>* src = nullptr;
+            switch (state.first)
+            {
+            case 1: { src = &sprite_white_only_data; break; }
+            case 2: { src = &sprite_gray_only_data; break; }
+            default: { src = &sprite_data; break; }
+            }
+
+            ::memcpy((void*)output_data.data(), (const void*)src->data(), sprite_bytes);
+            // applies background, if needed
+            if (state.second)
+            {
+                for (int i = 0; i < sprite_n_pixels; ++i)
+                {
+                    float alpha = (float)output_data.data()[i * 4 + 3] / 255.0f;
+                    output_data.data()[i * 4 + 0] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 0] * alpha);
+                    output_data.data()[i * 4 + 1] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 1] * alpha);
+                    output_data.data()[i * 4 + 2] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 2] * alpha);
+                    output_data.data()[i * 4 + 3] = (unsigned char)(128 * (1.0f - alpha) + output_data.data()[i * 4 + 3] * alpha);
+                }
+            }
+
+            int state_offset_px = sprite_offset_px + state_id * sprite_size_px;
             for (int j = 0; j < sprite_size_px; ++j)
             {
                 int data_offset = (state_offset_px + j * m_width) * 4;
-                ::memcpy((void*)&data.data()[data_offset], (const void*)&sprite_data.data()[j * sprite_size_px * 4], sprite_size_px * 4);
+                ::memcpy((void*)&data.data()[data_offset], (const void*)&output_data.data()[j * sprite_stride], sprite_stride);
             }
         }
 
@@ -216,6 +261,11 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
 
 
     m_source = filenames.front();
+    
+#if 0
+    // debug output
+    static int pass = 0;
+    ++pass;
 
     wxImage output(m_width, m_height);
     output.InitAlpha();
@@ -232,6 +282,7 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
     }
 
     output.SaveFile("C:/prusa/slic3r/svg_icons/temp/test_" + std::to_string(pass) + ".png", wxBITMAP_TYPE_PNG);
+#endif // 0
 
     return true;
 }
diff --git a/src/slic3r/GUI/GLTexture.hpp b/src/slic3r/GUI/GLTexture.hpp
index 55e5c4c07..9b1f04ea6 100644
--- a/src/slic3r/GUI/GLTexture.hpp
+++ b/src/slic3r/GUI/GLTexture.hpp
@@ -42,7 +42,15 @@ namespace GUI {
         bool load_from_svg_file(const std::string& filename, bool use_mipmaps, unsigned int max_size_px);
 #endif // ENABLE_TEXTURES_FROM_SVG
 #if ENABLE_SVG_ICONS
-        bool load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, unsigned int num_states, unsigned int sprite_size_px);
+        // meanings of states: (std::pair<int, bool>)
+        // first field (int):
+        // 0 -> no changes
+        // 1 -> use white only color variant
+        // 2 -> use gray only color variant
+        // second field (bool):
+        // false -> no changes
+        // true -> add background color
+        bool load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, const std::vector<std::pair<int, bool>>& states, unsigned int sprite_size_px);
 #endif // ENABLE_SVG_ICONS
         void reset();
 
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 5f5350299..144662c3f 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -124,8 +124,15 @@ GLToolbar::Layout::Layout()
 {
 }
 
+#if ENABLE_SVG_ICONS
+GLToolbar::GLToolbar(GLToolbar::EType type, const std::string& name)
+#else
 GLToolbar::GLToolbar(GLToolbar::EType type)
+#endif // ENABLE_SVG_ICONS
     : m_type(type)
+#if ENABLE_SVG_ICONS
+    , m_name(name)
+#endif // ENABLE_SVG_ICONS
     , m_enabled(false)
 #if ENABLE_SVG_ICONS
     , m_icons_texture_dirty(true)
@@ -1231,7 +1238,25 @@ bool GLToolbar::generate_icons_texture() const
             filenames.push_back(path + icon_filename);
     }
 
-    bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, GLToolbarItem::Num_States, (unsigned int)(m_layout.icons_size * m_layout.scale));
+    std::vector<std::pair<int, bool>> states;
+    if (m_name == "Top")
+    {
+        states.push_back(std::make_pair(1, false));
+        states.push_back(std::make_pair(0, false));
+        states.push_back(std::make_pair(2, false));
+        states.push_back(std::make_pair(0, false));
+        states.push_back(std::make_pair(0, false));
+    }
+    else if (m_name == "View")
+    {
+        states.push_back(std::make_pair(1, false));
+        states.push_back(std::make_pair(1, true));
+        states.push_back(std::make_pair(1, false));
+        states.push_back(std::make_pair(0, false));
+        states.push_back(std::make_pair(1, true));
+    }
+
+    bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_layout.icons_size * m_layout.scale));
     if (res)
         m_icons_texture_dirty = false;
 
diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp
index 30a9ff04d..e14f7b3bb 100644
--- a/src/slic3r/GUI/GLToolbar.hpp
+++ b/src/slic3r/GUI/GLToolbar.hpp
@@ -203,6 +203,9 @@ private:
     typedef std::vector<GLToolbarItem*> ItemsList;
 
     EType m_type;
+#if ENABLE_SVG_ICONS
+    std::string m_name;
+#endif // ENABLE_SVG_ICONS
     bool m_enabled;
 #if ENABLE_SVG_ICONS
     mutable GLTexture m_icons_texture;
@@ -216,7 +219,11 @@ private:
     ItemsList m_items;
 
 public:
+#if ENABLE_SVG_ICONS
+    GLToolbar(EType type, const std::string& name);
+#else
     explicit GLToolbar(EType type);
+#endif // ENABLE_SVG_ICONS
     ~GLToolbar();
 
 #if ENABLE_SVG_ICONS
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 6c2c3a1ea..24d366ced 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1178,7 +1178,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
     , sidebar(new Sidebar(q))
     , delayed_scene_refresh(false)
     , project_filename(wxEmptyString)
+#if ENABLE_SVG_ICONS
+    , view_toolbar(GLToolbar::Radio, "View")
+#else
     , view_toolbar(GLToolbar::Radio)
+#endif // ENABLE_SVG_ICONS
 {
     arranging.store(false);
     rotoptimizing.store(false);