イロウツシ

気分を言葉で選ばせないアプリ。水面に色を落として指でかき混ぜると、そのときの手の動きがそのまま1枚の絵として残ります。

App Store で配信中
  • アプリ
  • iPhone / iPad
  • Swift
  • SwiftUI
  • Metal
App Store で入手

できること

つくり

アプリ本体 Swift + SwiftUI。Swift Playgrounds の App Package として組んでいて、外部パッケージへの依存はありません。
水面 Metal で書いた流体シミュレーション。速度場、圧力投影、移流、渦度補強、顔料の混合をすべて GPU で処理しています。
顔料 ラグランジュ粒子として持ち、Beer–Lambert 則の減算混合で色を重ねます。粒子なので、時間が経っても拡散でぼやけません。
見た目 水面の高さ場から解析的に求めた法線で屈折とスペキュラを描き、粒状ノイズと、バンディングを避けるディザを重ねています。
入力 UIKit の生イベントから取得し、1フレーム内の coalesced touches をすべて流体へ渡します。5本同時のマルチタッチを、指ごとに独立したストロークとして記録・再生・数値化します。
記録の保存 履歴一覧の JSON には軽い情報だけを置き、画像は PNG 1枚、タッチ列は固定幅バイナリを LZFSE で圧縮して、記録ごとのディレクトリへ分けています。
再生・書き出し 保存した step からシミュレーションを回し直して水面を再構築します。MP4 は画面収録ではなく、保存 step からフレームを合成し直して 30fps で書き出しています。
音 効果音はアプリ内で合成。五音音階で16声まで同時に鳴ります。音源ファイルは持っていません。
セルフチェック XCTest を持てない環境なので、デバッグ起動時に走る自前の検査(SelfChecks.swift)で代用しています。
暗号 一切使っていません(export compliance の回答を同梱しています)。

技術的におもしろいところ

通り過ぎたあとも、尾が巻き続ける

移流に MacCormack 補正を入れてあります。単純なセミラグランジュ移流だと消えてしまう細い渦が、これで残ります。 指は「押す」のではなく、ドラッグの方向に沿って逆回転の渦の対を落としているので、指が通り過ぎたあとも水がしばらく巻き続けます。 減衰や追従の係数はすべて「毎秒」で表現してあり、60Hz の端末でも 120Hz の端末でも同じ動きになります。

「見える波」と「動かす波」を分ける

波紋の見た目の強さと、顔料に与える作用を別のパラメータにしています。しかも波紋は、顔料の速度ではなく位置を直接動かします。 顔料の速度は毎フレーム水流の速度へ引き戻されていて、濃いところでは時定数がおよそ 0.36 秒。波紋の寿命はそれより短いので、 速度を足す書き方では波紋が顔料をほとんど動かせない、と実測で分かったためです。見た目の調整と手応えの調整が、互いを壊さなくなりました。

顔料どうしを引き合わせないことにした

以前は顔料が集まろうとする「凝集」の力を入れていましたが、落ち着き先が丸い塊しかなく、時間が経つと水面が不透明な円で埋まって二度とほどけませんでした。 いまは水彩の縁だまりを、顔料を動かさずに再現しています。顔料の濃度場は同じまま、そこから水面パスの陰影として縁を描くので、絵が固まってしまう副作用がありません。

同じ記録は、何度再生しても同じ絵になる

シミュレーションを毎秒60 step に固定し、UIKit の入力を消費した実 step 番号、助走の step 数、Float32 の時刻と UInt16 の座標を記録の脇に保存しています。 再生は壁時計の時刻ではなく、この保存した step を優先します。速度は UITouch.timestamp 基準です(同じフレームの中の指の動きは、壁時計では区別できないため)。 予測タッチは速度の推定にだけ使い、顔料の位置には反映しません。 そのうえで、保存された simulationVersion を SimulationEngineRegistry が対応するエンジンへ明示的に振り分けます。 version 6 は定数も時計もインクの伝達率も含めて凍結してあり、知らない将来の version を黙って最新のシミュレーションへ流すことはしません。 古い記録の絵が、アプリの更新で作り変わってしまわないようにするためです。

点数を、先に見せない

4つの指標は上限で切り落とさず、100 へ漸近する曲線に載せています。一度速く動かしただけで満点にはなりません。 そのうえで、結果画面では既定で隠してあります。言葉で感情を分類しないアプリが数字を先に出すと、 結局その数字が新しいラベルになってしまうためです。

プライバシー・お問い合わせ

イロウツシは、記録を端末の中だけに保存します。アカウント登録・広告・アクセス解析・利用者を追跡する機能はありません。 くわしくはイロウツシ プライバシーポリシーをご覧ください。

ご意見・不具合のご報告は、Sizu dev のお問い合わせページからご連絡いただけます。