diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # Changelog for brillo-export
 
+## 0.2.1.0
+
+* Support brillo and brillo-rendering 3.0
+* SVG export: emit a comment for custom `Shader` pictures,
+  as they can't be represented in SVG
+* SVG export: omit GPU-compressed bitmaps (with a comment)
+  instead of misinterpreting their data as RGBA pixels
+
 ## 0.1.0.4
 
 * Forked from gloss-export
diff --git a/brillo-export.cabal b/brillo-export.cabal
--- a/brillo-export.cabal
+++ b/brillo-export.cabal
@@ -1,5 +1,5 @@
 name:               brillo-export
-version:            0.2.0.0
+version:            0.2.1.0
 synopsis:
   Export Brillo pictures to png, bmp, tga, tiff, gif, svg and juicy-pixels-image
 
@@ -53,7 +53,7 @@
   ghc-options:      -fwarn-unused-imports
   build-depends:
       base              >=4.7   && <5
-    , brillo-rendering  >=2.0   && <3.0
+    , brillo-rendering  >=3.0   && <4.0
     , bytestring        >=0.11  && <0.13
     , GLFW-b            >=1.0.0 && <4
     , JuicyPixels       >=3.2   && <4
@@ -82,7 +82,7 @@
   ghc-options:      -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       base           >=4.7 && <5
-    , brillo         >=2.0 && <3.0
+    , brillo         >=3.0 && <4.0
     , brillo-export
 
   other-modules:    Paths_brillo_export
@@ -95,7 +95,7 @@
   ghc-options:      -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       base           >=4.7   && <5
-    , brillo         >=2.0   && <3.0
+    , brillo         >=3.0   && <4.0
     , brillo-export
     , directory
     , filepath
@@ -113,7 +113,7 @@
   ghc-options:      -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       base           >=4.7 && <5
-    , brillo         >=2.0 && <3.0
+    , brillo         >=3.0 && <4.0
     , brillo-export
     , directory
     , filepath
@@ -128,7 +128,7 @@
   ghc-options:      -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       base           >=4.7   && <5
-    , brillo         >=2.0   && <3.0
+    , brillo         >=3.0   && <4.0
     , brillo-export
     , bytestring     >=0.11  && <0.13
     , directory
diff --git a/src/Brillo/Export/SVG.hs b/src/Brillo/Export/SVG.hs
--- a/src/Brillo/Export/SVG.hs
+++ b/src/Brillo/Export/SVG.hs
@@ -20,8 +20,10 @@
 
 import Brillo.Rendering (
   BitmapData (..),
+  BitmapFormat (..),
   Color,
   Picture (..),
+  PixelFormat (..),
   Point,
   Rectangle (..),
   makeColor,
@@ -253,6 +255,8 @@
     , renderPicture rs picture
     , "  </g>\n"
     ]
+renderPicture _ (Shader _) =
+  "  <!-- Custom shader: not supported in SVG export -->\n"
 renderPicture rs (Pictures pictures) =
   T.concat (map (renderPicture rs) pictures)
 
@@ -617,63 +621,67 @@
 
 -- | Render a bitmap image as a data URI embedded image
 renderBitmap :: RenderState -> BitmapData -> Maybe Rectangle -> Text
-renderBitmap _ bitmapData maybeRect =
-  let
-    BitmapData _len _fmt (bmpWidth, bmpHeight) _cache fptr = bitmapData
+renderBitmap _ bitmapData maybeRect
+  | PxCompressed _ <- pixelFormat (bitmapFormat bitmapData) =
+      -- SVG export cannot decode GPU-compressed payloads; emit a placeholder.
+      "  <!-- compressed bitmap omitted from SVG export -->\n"
+  | otherwise =
+      let
+        BitmapData _len _fmt (bmpWidth, bmpHeight) _cache fptr = bitmapData
 
-    -- Get the actual section to render
-    (srcX, srcY, width, height) = case maybeRect of
-      Nothing -> (0, 0, bmpWidth, bmpHeight)
-      Just (Rectangle (rx, ry) (rw, rh)) -> (rx, ry, rw, rh)
+        -- Get the actual section to render
+        (srcX, srcY, width, height) = case maybeRect of
+          Nothing -> (0, 0, bmpWidth, bmpHeight)
+          Just (Rectangle (rx, ry) (rw, rh)) -> (rx, ry, rw, rh)
 
-    -- Create a base64 PNG data URI
-    dataUri = unsafePerformIO $ do
-      withForeignPtr fptr $ \ptr -> do
-        -- Read pixel data
-        let pixelCount = bmpWidth * bmpHeight * 4
-        pixelData <- V.generateM pixelCount $ \i -> do
-          let bytePtr = castPtr ptr :: Ptr Word8
-          peekElemOff bytePtr i
+        -- Create a base64 PNG data URI
+        dataUri = unsafePerformIO $ do
+          withForeignPtr fptr $ \ptr -> do
+            -- Read pixel data
+            let pixelCount = bmpWidth * bmpHeight * 4
+            pixelData <- V.generateM pixelCount $ \i -> do
+              let bytePtr = castPtr ptr :: Ptr Word8
+              peekElemOff bytePtr i
 
-        -- Create JuicyPixels image
-        let img = JP.Image bmpWidth bmpHeight pixelData :: JP.Image JP.PixelRGBA8
+            -- Create JuicyPixels image
+            let img = JP.Image bmpWidth bmpHeight pixelData :: JP.Image JP.PixelRGBA8
 
-        -- Encode to PNG and then base64
-        let pngBytes = JP.encodePng img
-        pure $ "data:image/png;base64," ++ encodeBase64 (BL.unpack pngBytes)
+            -- Encode to PNG and then base64
+            let pngBytes = JP.encodePng img
+            pure $ "data:image/png;base64," ++ encodeBase64 (BL.unpack pngBytes)
 
-    -- Center the image at origin (Brillo convention)
-    halfW = fromIntegral width / 2 :: Float
-    halfH = fromIntegral height / 2 :: Float
-  in
-    T.concat
-      [ "  <image x=\""
-      , T.pack (showFloat (-halfW))
-      , "\" y=\""
-      , T.pack (showFloat (-halfH))
-      , "\" width=\""
-      , T.pack (show width)
-      , "\" height=\""
-      , T.pack (show height)
-      , "\" xlink:href=\""
-      , T.pack dataUri
-      , "\""
-      , if srcX /= 0 || srcY /= 0
-          then
-            T.concat
-              [ " preserveAspectRatio=\"xMinYMin slice\" viewBox=\""
-              , T.pack (show srcX)
-              , " "
-              , T.pack (show srcY)
-              , " "
-              , T.pack (show width)
-              , " "
-              , T.pack (show height)
-              , "\""
-              ]
-          else ""
-      , "/>\n"
-      ]
+        -- Center the image at origin (Brillo convention)
+        halfW = fromIntegral width / 2 :: Float
+        halfH = fromIntegral height / 2 :: Float
+      in
+        T.concat
+          [ "  <image x=\""
+          , T.pack (showFloat (-halfW))
+          , "\" y=\""
+          , T.pack (showFloat (-halfH))
+          , "\" width=\""
+          , T.pack (show width)
+          , "\" height=\""
+          , T.pack (show height)
+          , "\" xlink:href=\""
+          , T.pack dataUri
+          , "\""
+          , if srcX /= 0 || srcY /= 0
+              then
+                T.concat
+                  [ " preserveAspectRatio=\"xMinYMin slice\" viewBox=\""
+                  , T.pack (show srcX)
+                  , " "
+                  , T.pack (show srcY)
+                  , " "
+                  , T.pack (show width)
+                  , " "
+                  , T.pack (show height)
+                  , "\""
+                  ]
+              else ""
+          , "/>\n"
+          ]
 
 
 -- | Simple base64 encoding
