Skip to content

[api] Add SkSL image filter support (SKRuntimeEffect.ToImageFilter) #3776

Description

@mattleibow

Summary

SkImageFilters::RuntimeShader allows running custom SkSL shader programs as image filters, enabling users to write arbitrary GPU-accelerated image processing effects (custom blurs, distortions, color grading, edge detection, etc.) and compose them with built-in filters in the image filter graph.

This API was introduced in Skia m98 and enhanced with a maxSampleRadius parameter in m116 for proper boundary handling when shaders sample neighboring pixels.

Why this matters

Today, SkiaSharp users who want custom image filter effects must either:

  • Build a shader and wrap it manually with SKImageFilter.CreateShader (which does not receive the filtered input image — it is a leaf filter)
  • Chain multiple built-in filters together, which is limited to pre-defined operations

CreateRuntimeShader bridges this gap: it lets any SkSL shader receive the filtered image as a child shader input, process it per-pixel on the GPU, and participate in the filter composition graph. This is the most powerful image filter factory — essentially "run any SkSL as a filter."

Use cases

  • Custom blur variants — directional blur, tilt-shift, lens blur
  • Distortion effects — ripple, swirl, barrel distortion, heat haze
  • Color grading — film LUTs, split toning, selective color adjustment
  • Edge detection and outline — Sobel, Laplacian, artistic outlines
  • Compositing — custom blend modes beyond built-in options
  • Post-processing pipelines — chain with built-in blur/shadow/color filters

API surface

// Apply a runtime shader as an image filter
SKImageFilter.CreateRuntimeShader(
    SKRuntimeShaderBuilder builder,
    string childShaderName,
    SKImageFilter? input = null);

// With explicit sample radius for shaders that read neighboring pixels
SKImageFilter.CreateRuntimeShader(
    SKRuntimeShaderBuilder builder,
    float maxSampleRadius,
    string childShaderName,
    SKImageFilter? input = null);

Upstream references

Part of #3680

Metadata

Metadata

Assignees

No one assigned

    Labels

    cost/l~2 Cross-cutting change, real design work, multiple componentspriority/1Important: should land this milestone. Must fix by RC.type/enhancementupgrading/4.xIssues and discussions relating to the upgrade from 3.x to 4.x

    Type

    No type

    Projects

    Status
    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions