Tutorials › Launch Lab Notes › Chapter 25

One Uniform, Three Effects

LabChapter 25 of the Launch Lab Notes22 minAugust 20, 2026Intermediate

Three SwiftUI shader modifiers. One animated float. If the unmodified card ever moves with t, the demo is broken.

Filmstrip: NONE stays still while COLOR hue-shifts, DISTORT waves, and LAYER glows as shared t cycles.

t = 0.00

-mode t0

t 0.00 pinned. NONE control purple-orange HARBOR. COLOR matches NONE. DISTORT already wavy. LAYER near NONE. SHARED ShaderLibrary · one t.
ColumnModifierAt t = 0.00
NONE— (control)purple→orange, yellow beacon
COLORcolorEffectmatches NONE (hue identity)
DISTORTdistortionEffectwavy edges — spatial sine still runs at phase 0
LAYERlayerEffectnear NONE (glow lift ≈ 0.15)

Distortion is not “off” at zero — sin(x + t·2π) still waves in x. t only slides the phase.

t = 0.35

-mode t35

t 0.35 pinned. NONE unchanged. COLOR blue-green with purple circle. DISTORT wavy purple-orange. LAYER brighter glow.

NONE is still the dusk card. COLOR has rotated — blue/green gradient, purple beacon. DISTORT keeps the original hues but warps the glyph. LAYER lifts highlights.

t = 0.70

-mode t70

t 0.70 pinned. NONE unchanged control. COLOR green-brown. DISTORT wavy. LAYER pastel pink/cream glow.
ColumnObserved at t = 0.70
NONEunchanged purple→orange (control)
COLORgreen/brown shift, light-green beacon
DISTORTgeometry wavy; hues like NONE
LAYERpastel pink→cream, pale beacon
.colorEffect(ShaderLibrary.harborHue(.float(t)))
.distortionEffect(ShaderLibrary.harborWave(.float(t)), maxSampleOffset: …)
.layerEffect(ShaderLibrary.harborGlow(.float(t)), maxSampleOffset: .zero)

Three [[ stitchable ]] functions in LabShaders.metal. One t from the bench.

What each modifier is allowed to do

colorEffect rewrites a color. distortionEffect rewrites a sample position. layerEffect may sample the view’s layer. NONE proves the card itself is not animating in SwiftUI — only the shaders that read t.

Mini-exercise

Pass 1 - t into DISTORT only. COLOR and LAYER should still track the meter; DISTORT should run out of phase.

Challenges

  1. Add a fifth column that stacks colorEffect then distortionEffect on the same card.
  2. Drive t with TimelineView(.animation) instead of asyncAfter.
  3. Visualize maxSampleOffset by drawing a hairline inset on the DISTORT card.
  4. Port harborHue to a Metal Performance Shader graph and compare stills.
  5. XCUITest: assert the t label shows 0.70 under -mode t70.

Key Points

Next up: Charts — the same dataset drawn honestly and misleadingly, side by side.

SwiftUI
SwiftUI tutorials for building native app screens, layouts, navigation, and state-driven interfaces.
Swift
Swift fundamentals for app developers who want to understand the language behind real iOS and macOS apps.
Ship iOS
Shipping workflows for iOS apps.
📚 Go deeper with LIPAI WANG’s hands-on Udemy bootcampsBrowse all courses →
← Ch 24: Four Stages, One StillCh 26: Same Numbers, Two Stories→
SwiftUIUltimate SwiftUI SeriesSwiftUI tutorials for building native app screens, layouts, navigation, and state-driven interfaces.SwiftUltimate Swift SeriesSwift fundamentals for app developers who want to understand the language behind real iOS and macOS apps.Ship iOSShip iOS Apps SeriesShipping workflows for iOS apps: signing, TestFlight, App Store Connect, CI, and release hygiene.

Ship your apps faster

When you're ready to publish your Swift app to the App Store, Simple App Shipper handles metadata, screenshots, TestFlight, and submissions — all in one place.

Try Simple App Shipper
5 free articles remainingSubscribe for unlimited access