IRO UTSUSHI

지금의 기분에 이름을 붙이라고 하지 않는 앱입니다. 수면에 색을 떨어뜨리고 손가락으로 저으면, 그때의 손놀림이 그대로 한 장의 그림으로 남습니다.

App Store에서 이용 가능
  • 앱
  • iPhone / iPad
  • Swift
  • SwiftUI
  • Metal
App Store에서 다운로드

할 수 있는 것

만듦새

앱 본체 Swift + SwiftUI. Swift Playgrounds의 App Package로 만들었으며, 외부 패키지 의존성은 하나도 없습니다.
수면 Metal로 작성한 유체 시뮬레이션. 속도장, 압력 투영, 이류, 와도 보강, 안료 혼합을 모두 GPU에서 처리합니다.
안료 라그랑주 입자로 다루고, Beer–Lambert 법칙에 따른 감산 혼합으로 색을 겹칩니다. 입자이기 때문에 시간이 지나도 확산으로 뭉개지지 않습니다.
겉모습 수면 높이장에서 해석적으로 구한 법선으로 굴절과 스페큘러를 그리고, 그 위에 입자 노이즈와 밴딩을 피하기 위한 디더를 얹습니다.
입력 UIKit의 원시 이벤트에서 받아, 한 프레임 안의 coalesced touches를 모두 유체로 넘깁니다. 최대 5개의 동시 터치를 손가락별로 독립된 스트로크로 기록·재생·수치화합니다.
기록의 저장 기록 목록 JSON에는 가벼운 정보만 담고, 이미지는 PNG 한 장, 터치 열은 고정 폭 바이너리를 LZFSE로 압축해 기록마다 별도 디렉터리에 저장합니다.
재생·내보내기 저장된 step에서 시뮬레이션을 다시 돌려 수면을 재구축합니다. MP4는 화면 녹화가 아니라, 저장된 step에서 프레임을 다시 합성해 30 fps로 씁니다.
소리 효과음은 앱 안에서 합성합니다. 5음 음계로 최대 16성까지 동시에 울리며, 음원 파일은 두지 않습니다.
셀프 체크 XCTest를 둘 수 없는 환경이라, 디버그 실행 시 돌아가는 자체 점검(SelfChecks.swift)으로 대신합니다.
암호화 전혀 사용하지 않습니다(export compliance 답변을 함께 넣어 두었습니다).

기술적으로 재미있는 부분

손가락이 지나간 뒤에도 꼬리가 계속 말립니다

이류에 MacCormack 보정을 넣었습니다. 단순한 세미라그랑주 이류라면 사라져 버릴 가느다란 소용돌이가 이것으로 남습니다. 손가락은 물을 「미는」 것이 아니라 드래그 방향을 따라 서로 반대로 도는 소용돌이 쌍을 떨어뜨리기 때문에, 손가락이 지나간 뒤에도 물이 한동안 계속 말립니다. 감쇠와 추종 계수는 모두 「초당」으로 표현해 두어서 60 Hz 기기든 120 Hz 기기든 같은 움직임이 됩니다.

「보이는 물결」과 「움직이는 물결」을 나눕니다

물결의 겉보기 세기와 안료에 미치는 작용을 서로 다른 파라미터로 두었습니다. 게다가 물결은 안료의 속도가 아니라 위치를 직접 움직입니다. 안료의 속도는 매 프레임 물살의 속도로 끌려 돌아가는데, 짙은 곳에서는 시간 상수가 약 0.36초입니다. 물결의 수명은 그보다 짧아서, 속도를 더하는 방식으로는 물결이 안료를 거의 움직이지 못한다는 것이 실측으로 드러났습니다. 겉모습을 다듬는 일과 손맛을 다듬는 일이 서로를 망가뜨리지 않게 되었습니다.

안료끼리 서로 끌어당기지 않게 했습니다

예전에는 안료가 모이려는 「응집」 힘이 있었지만, 가라앉을 곳이 둥근 덩어리뿐이라 시간이 지나면 수면이 불투명한 원으로 가득 차 다시는 풀리지 않았습니다. 지금은 수채화의 가장자리 얼룩을 안료를 움직이지 않고 재현합니다. 안료의 농도장은 그대로 두고 거기에서 수면 패스의 음영으로 가장자리를 그리기 때문에, 그림이 굳어 버리는 부작용이 없습니다.

같은 기록은 몇 번을 재생해도 같은 그림이 됩니다

시뮬레이션을 초당 60 step으로 고정하고, UIKit 입력을 소비한 실제 step 번호, 도움닫기 step 수, Float32 시각과 UInt16 좌표를 기록 옆에 함께 저장합니다. 재생은 벽시계 시각보다 이 저장된 step을 우선합니다. 속도는 UITouch.timestamp 기준입니다(같은 프레임 안의 움직임은 벽시계로는 구분할 수 없기 때문입니다). 예측 터치는 속도 추정에만 쓰고, 안료가 놓이는 위치에는 반영하지 않습니다.

그 위에 SimulationEngineRegistry가 저장된 simulationVersion을 대응하는 엔진으로 명시적으로 분배합니다. version 6은 상수도 시계도 잉크 전달률까지 포함해 동결해 두었고, 알 수 없는 미래의 version을 말없이 최신 시뮬레이션으로 흘려보내지 않습니다. 앱을 업데이트했다고 해서 예전 기록의 그림이 다른 그림으로 다시 만들어지지 않도록 하기 위해서입니다.

점수를 먼저 보여 주지 않습니다

네 가지 지표는 상한에서 잘라 내지 않고 100에 점근하는 곡선에 올려 두었습니다. 한 번 빠르게 움직였다고 만점이 되지는 않습니다. 그러고도 결과 화면에서는 기본적으로 숨겨 둡니다. 감정을 말로 분류하지 않는 앱이 숫자부터 내밀면, 결국 그 숫자가 새로운 이름표가 되어 버리기 때문입니다.

개인정보 · 문의

IRO UTSUSHI는 기록을 단말기 안에만 저장합니다. 계정 등록, 광고, 접속 분석, 이용자를 추적하는 기능은 없습니다. 자세한 내용은 IRO UTSUSHI 개인정보 처리방침을 확인해 주세요.

의견이나 오류 제보는 Sizu dev의 문의 페이지에서도 보내실 수 있습니다.