Upgrade to Pro — share decks privately, control downloads, hide ads and more …

『SwiftUIによるカスタムビジュアルエフェクトの作成』を真似して作ってみた

miharu
September 20, 2024

 『SwiftUIによるカスタムビジュアルエフェクトの作成』を真似して作ってみた

Chiba.swift #1
2024/09/20
https://chibaswift.connpass.com/event/328367/

WWDC動画
・Create custom visual effects with SwiftUI
https://developer.apple.com/wwdc24/10151

Sample Code
https://developer.apple.com/documentation/SwiftUI/Creating-visual-effects-with-SwiftUI
・iOS 18.0+ | iPadOS 18.0+ | Xcode 16.0+

「Metal Shading Language Specification」
https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf

miharu

September 20, 2024
Tweet

More Decks by miharu

Other Decks in Programming

Transcript

  1. αϯϓϧॆ࣮ͯ͠·͢ ✨ • WWDCಈը • Create custom visual e ff

    ects with SwiftUI • https://developer.apple.com/wwdc24/10151 • Sample Code • https://developer.apple.com/documentation/SwiftUI/Creating-visual- e ff ects-with-SwiftUI • iOS 18.0+ | iPadOS 18.0+ | Xcode 16.0+
  2. View import SwiftUI #Preview("Ripple") { @Previewable @State var counter: Int

    = 0 @Previewable @State var origin: CGPoint = .zero VStack { Spacer() Image("palm_tree") .resizable() .aspectRatio(contentMode: .fit) .clipShape(RoundedRectangle(cornerRadius: 24)) .onPressingChanged { point in if let point { origin = point counter += 1 } } .modifier(RippleEffect(at: origin, trigger: counter)) Spacer() } .padding() }
  3. View import SwiftUI #Preview("Ripple") { @Previewable @State var counter: Int

    = 0 @Previewable @State var origin: CGPoint = .zero VStack { Spacer() Image("palm_tree") .resizable() .aspectRatio(contentMode: .fit) .clipShape(RoundedRectangle(cornerRadius: 24)) .onPressingChanged { point in if let point { origin = point counter += 1 } } .modifier(RippleEffect(at: origin, trigger: counter)) Spacer() } .padding() } onPressingChanged͔ΒλοϓҐ ஔΛड͚औ͍ͬͯΔɻ Modi f ierͷதͰɺ͍Ζ͍Ζ΍ͬͯɺ Metal ShaderΛSwiftUIʹม׵͢Δ ίʔυΛݺΜͰ͍Δɻ
  4. Metal Shader Ripple.metalɹίʔυͷશମ #include <metal_stdlib> #include <SwiftUI/SwiftUI.h> using namespace metal;

    [[ stitchable ]] half4 Ripple( float2 position, SwiftUI : : Layer layer, float2 origin, float time, float amplitude, float frequency, float decay, float speed ) { / / The distance of the current pixel position from `origin`. float distance = length(position - origin); / / The amount of time it takes for the ripple to arrive at the current pixel position. float delay = distance / speed; / / Adjust for delay, clamp to 0. time -= delay; time = max(0.0, time); / / The ripple is a sine wave that Metal scales by an exponential decay / / function. float rippleAmount = amplitude * sin(frequency * time) * exp(-decay * time); / / A vector of length `amplitude` that points away from position. float2 n = normalize(position - origin); / / Scale `n` by the ripple amount at the current pixel position and add it / / to the current pixel position. / / / / This new position moves toward or away from `origin` based on the / / sign and magnitude of `rippleAmount`. float2 newPosition = position + rippleAmount * n; / / Sample the layer at the new position. half4 color = layer.sample(newPosition); / / Lighten or darken the color based on the ripple amount and its alpha / / component. color.rgb += 0.3 * (rippleAmount / amplitude) * color.a; return color; }
  5. Metal Shader Ripple.metalɹҾ਺ͱ໭Γ஋͸͜Μͳײ͡ [[ stitchable ]] half4 Ripple( float2 position,

    SwiftUI : : Layer layer, float2 origin, float time, float amplitude, float frequency, float decay, float speed ) { // தུ return color; } ֤ϐΫηϧͷҐஔͷ৭Λมߋͯ͠ฦ͍ͯ͠Δɻ ʬϙΠϯτʭ half4: 16Ϗοτුಈখ਺఺਺ͷ̐੒෼͔ΒͳΔ ϕΫτϧɻ͜ͷܕ͸ɺ৭ͷ੺ɾ྘ɾ੨ɾΞϧϑΝ ஋ͷ֤੒෼ΛΤϯίʔυ͢Δɻ f loat2: 32Ϗοτුಈখ਺఺਺ͷ̎੒෼͔Βͳ ΔϕΫτϧɻ2Dͷ఺΍࣍ݩʹΑ͘࢖ΘΕΔ ʢposition: ϐΫηϧͷҐஔʣɻ
  6. Metal Shader Ripple.metalɹ೾໲͔ͩΒsin࢖ͬͯΔ // The ripple is a sine wave

    that Metal scales by an exponential decay // function. float rippleAmount = amplitude * sin(frequency * time) * exp(-decay * time); // Lighten or darken the color based on the ripple amount and its alpha // component. color.rgb += 0.3 * (rippleAmount / amplitude) * color.a; ৼ෯ʢ೾ͷߴ͞΍ڧ͞ʣ प೾਺ʢ೾ͷ଎͞ɺ೾ͷࡉ͔͞ʣ ݮਰ ೾ͷӨڹʹΑͬͯϐΫηϧͷ৭ͷ໌Δ͕͞มΘΔ͜ͱΛදݱ͍ͯ͠Δɻ RGB͸Ճ๏ࠞ৭Λجʹ͓ͯ͠Γɺ஋͕େ͖͘ͳΔ΄Ͳ৭͕໌Δ͘ͳΔɻ
  7. ࠓޙ΍Γ͍ͨ͜ͱ • Metal Shading LanguageͷཧղΛਂΊ͍ͨɻ • ʮMetal Shading Language Speci

    f icationʯ • https://developer.apple.com/metal/Metal-Shading- Language-Speci f ication.pdf • ଞͷΞΠσΞ΋ग़ͯ͠࡞ͬͯΈ͍ͨɻ • ଞʹͲ͏͍͏͜ͱ͕Ͱ͖Δͷ͔΋ͬͱ஌Γ͍ͨɻ •