diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c
index ae8532eb95395..be24a056c9ecf 100644
--- a/shared-bindings/vectorio/VectorShape.c
+++ b/shared-bindings/vectorio/VectorShape.c
@@ -21,7 +21,7 @@
 
 //| class VectorShape:
 //|     def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None:
-//|         """Binds a vector shape to a location and pixel color
+//|         """Binds a vector shape to a location and pixel shader. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0.
 //|
 //|            :param shape: The shape to draw.
 //|            :param pixel_shader: The pixel shader that produces colors from values
diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c
index f0b6a725c1467..fb8ce963f1140 100644
--- a/shared-module/vectorio/VectorShape.c
+++ b/shared-module/vectorio/VectorShape.c
@@ -214,18 +214,30 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ
             #endif
             VECTORIO_SHAPE_PIXEL_DEBUG(" -> %d", input_pixel.pixel);
 
-            output_pixel.opaque = true;
-            if (self->pixel_shader == mp_const_none) {
-                output_pixel.pixel = input_pixel.pixel;
-            } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) {
-                output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel);
-            } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) {
-                displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
-            }
-            if (!output_pixel.opaque) {
+            // vectorio shapes use 0 to mean "area is not covered."
+            // We can skip all the rest of the work for this pixel if it's not currently covered by the shape.
+            if (input_pixel.pixel == 0) {
                 VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n");
                 full_coverage = false;
             } else {
+                // Pixel is not transparent. Let's pull the pixel value index down to 0-base for more error-resistant palettes.
+                input_pixel.pixel -= 1;
+                output_pixel.opaque = true;
+
+                if (self->pixel_shader == mp_const_none) {
+                    output_pixel.pixel = input_pixel.pixel;
+                } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) {
+                    output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel);
+                } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) {
+                    displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
+                }
+
+                // We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily.
+                if (!output_pixel.opaque) {
+                    VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)\n");
+                    full_coverage = false;
+                }
+
                 *mask_doubleword |= 1u << mask_bit;
                 if (colorspace->depth == 16) {
                     VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel);