Mirage: Cloudy Evolves from a Blur Library to a Graphics Effect Toolkit
Create cross-platform graphics effects with a single API.
1The Evolution of Cloudy
Cloudy began as a simple blur library for Compose Multiplatform. Modifier.cloudy captures and blurs the backdrop behind a node with a straightforward API. With Mirage, the library is evolving into a general graphics effect toolkit, allowing custom GPU shader effects beyond just blurring.
2Shader Languages and Compatibility
Mirage supports different shader languages like AGSL on Android and SKSL on skiko. Since both belong to the Skia family, most kernels align almost verbatim. However, this compatibility isn't guaranteed for more distant languages like GLSL. Mirage abstracts this complexity, offering a unified API.
3RuntimeShader and Skia RuntimeEffect
Running shaders consistently across platforms is challenging. Android uses RuntimeShader, while skiko relies on Skia RuntimeEffect. Each has its own way to compile, bind uniforms, and manage effects. Mirage handles this complexity, letting developers write shaders once.
4The Optic Hierarchy
Mirage introduces the Optic sealed hierarchy, enabling developers to compose shader types into an ordered plan. Adding or removing an effect is as simple as editing a single line of code. Built-in optics are just the starting point; users can create custom effects.
5Content and Backdrop Effects
Mirage works with two pixel sources: the node's content or its backdrop. Modifier.mirage { … } applies effects to the node's content, while Modifier.mirage(sky = …) { … } processes the backdrop. This flexibility allows for creative visual designs.
6Demo Application
The Mirage demo showcases a plan block and a catalog of effects. For example, the Iridescent recipe can be applied full-bleed over a poster. This demonstrates the library's versatility, allowing users to experiment and integrate effects into their projects.
7Mirage Architecture
This article explores Mirage's architecture: how a plan is declared once and bound per draw, the differences between Optic types, and how internal components like the compiler and program cache transform plans into pixels.
8Common Use Cases
Mirage simplifies scenarios like stacking effects. For instance, tinting a backdrop with duotone and overlaying an iridescent foil can be done effortlessly. Traditional methods require manual shader management per frame, but Mirage streamlines the process.
9Effect Reusability
Mirage prevents effects from being tied to draw sites. Reusing a duotone-plus-foil recipe across screens no longer requires copying setup code. Centralized effect management enhances reusability and reduces code duplication.
10Platform Support and Backward Compatibility
Mirage gracefully handles devices below API 33 (lacking RuntimeShader) by skipping filters and drawing the raw source. This ensures backward compatibility without crashes, providing a consistent experience across platforms.
11Creating Custom Effects
Mirage empowers users to craft custom shader effects. Built-in optics are just the beginning. Developers can leverage the Optic hierarchy to create unique visual styles and integrate them seamlessly into their applications.
12Conclusion and Future
Mirage transforms Cloudy from a blur tool into a comprehensive graphics effect library. Developers can create cross-platform shader effects with a single API, unlocking new possibilities for UI designers. Future updates may include more effects and broader platform support.