Skip to content

SVG Export Limitation: Noise Filters Not Supported #445

@softmarshmallow

Description

@softmarshmallow

SVG Export Limitation: Noise Filters Not Supported

Issue

SVG export does not properly render noise effects (Perlin noise, turbulence). When using Skia's svg::Canvas to export scenes containing noise shaders, the noise effects are omitted from the output SVG.

Root Cause

Skia's SVG backend does not provide bindings to convert shader-based effects to their SVG filter primitive equivalents. Specifically:

  • Shader::fractal_perlin_noise() does not export as <feTurbulence type="fractalNoise">
  • Shader::turbulence_perlin_noise() does not export as <feTurbulence type="turbulence">
  • Color filters applied to shaders are not converted to <feColorMatrix>

The skia_safe::svg::Canvas only handles basic vector primitives and rasterizes or omits shader-based effects.

Expected Behavior

When exporting a scene with noise effects to SVG, the output should include appropriate SVG filter primitives:

<defs>
  <filter id="noise">
    <feTurbulence type="fractalNoise" baseFrequency="0.05" numOctaves="4"/>
  </filter>
</defs>
<rect filter="url(#noise)" width="100" height="100"/>

Current Behavior

The SVG export produces empty rectangles without filter effects:

<rect width="400" height="400"/>
<!-- noise shader effect is omitted -->

Impact

  • PNG export: ✅ Works correctly
  • SVG export: ❌ Noise effects not rendered
  • Use cases affected:
    • Figma-like noise textures
    • Procedural texture generation
    • Any shader-based effects requiring SVG output

Workarounds

1. PNG Export Only (Current)

Use PNG format for noise effects, as raster formats properly capture shader output.

2. Manual SVG Filter Generation (Not Recommended)

Manually construct SVG with feTurbulence filters using string templating. This approach:

  • ❌ Bypasses the proper export pipeline
  • ❌ Creates maintenance burden
  • ❌ Doesn't scale to complex scenes

3. Future: Proper SVG Export Layer

Build a dedicated SVG exporter that:

  • Understands Grida's paint/effect types
  • Maps shader effects to SVG filter primitives
  • Integrates with existing export infrastructure
  • See crates/grida-canvas/src/export/export_as_svg.rs for starting point

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions