その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

try! Swift 2018の思い出 #tryswiftconf

try! Swiftは非日常感がありどの年も色々と思い出があるのですが、今年はスピーカーとしての参加ということで最初にお声がけいただいた9月から約半年感、ずっとtry! Swiftを意識して行動してきたといっても過言ではなく、感慨深さもひとしおでした。

終わってからの2週間、仕事の状況がガラッと変わったこともありしばらくそんなことも忘れるほど忙殺されていたのですが、最近アップされた公式の写真を見ていると色々と思い出されたので、(もう発表内容についての補足記事は書いたものの、)せっかくなので発表内容以外の振り返りについて書いておきたいと思います。

2017年9月: 打診いただく

9月某日、オーガナイザの pancake 氏よりお話をいただきました。

iOS Top 10 Conferences にも選ばれ、海外からも多数の参加者のある名カンファレンスに招待されるチャンスはもう二度とないかもしれません。実際のところ、try! Swift Tokyoは東京開催で同時通訳が行われるので僕でも呼んでいただけましたが、英語主体のカンファレンスではなかなか厳しいのが現実だと思います。1

そんなわけで、打診いただいたその場で二つ返事でお受けしました。

この時点で発表の軸はMetalしかないかなと考えていました。僕が2017年に興味をもって取り組んでいたのは機械学習、Metal、ARあたりですが、機械学習は結局実務で取り組む機会がなく 2、ARはまだARKitの薄いレイヤしか知らないのでカンファレンスで話すような体系立った知見がない。普通に仕事で使ってる&他に話す人もいなさそうなMetalしかないだろう、と。

〜2018年1月: 技術調査

12月にはMetalのアドベントカレンダーも立て、どれだけMetal好きなんだ、と思われたかもしれませんが、常に頭にあったのはtry! Swiftで発表するからには、知見をしっかりためないと、というところでした。

GPUまわりはもともと興味のあったところですが、try! Swift登壇が決まってなかったら、あんなにMetalMetalせず、機械学習とかARとかその他iOSの新機能とか、もうちょっと幅広く勉強したり記事書いたりしてたと思います。

2017年12月: 発表のタイトルと概要が決定

12月だったかに発表のタイトルと概要を3案ずつ提出して、ナターシャさんがチョイスする、というのがありました。

僕が出した3案はどれもMetal縛りでしたが、それぞれちょっとずつ「切り口」が違ってました。

  • UIImageView vs Metal
    • 今回のやつ。Metal自体の解説ではなく、「普段意識する機会の少ないGPUレイヤに目を向けてみる」というのがコンセプト。

MetalはGPUへのアクセスを提供するAPIで、OpenGLより10倍速いという謳い文句で登場しました。本セッションではMetalの基礎を解説しつつ、そのグラフィックス描画性能をUIImageViewと比較してみます。 MetalのAPIを直接利用する機会がなくても、Metalはあなたのアプリの裏で暗躍しています。身近なクラスとの比較を通じて、普段我々が意識することのないGPUのレイヤで何が起きているのか、目を向けてみるきっかけになればと思います。

  • 非ゲームアプリにおけるMetal / Metal for non-game apps
    • 「Metalってゲーム用でしょ?」いやいやそうじゃないアプリでも実際に使ってるんですよ、ということを示しつつMetalの基礎について話す。

「Metal=本格的なゲーム向けのAPI」と考えてしまい、興味の対象外としている開発者は多いのではないでしょうか。そんなことはなく、Metalはグラフィックス処理から機械学習の計算まで、「非ゲーム」アプリにおいても大いに活用の場があります。本セッションでは、実際にAppStoreにリリースされているアプリでのMetal活用事例を題材に、その基礎と実装方法について解説していきます。

  • iOS GPU Programming
    • 普通にMetalについて解説する。ただしなるべくGPUプログラミング未経験者にもわかりやすく。

GPUはその名の通りグラフィックス向けのプロセッサですが、今ではその並列演算処理能力に着目して、ディープラーニングの行列演算のような汎用的な計算で用いられるケースも増えてきています。 そんなGPUへのアクセスを提供するAPIが、Metalです。本セッションでは、Metalを利用してiOSバイスGPUで処理を行う方法について、初めての方でも理解できるよう基礎から丁寧に解説します。

で、"UIImage vs Metal"がチョイスされたわけですが、たとえばもし2番目のになったとしたら、Fyusion社の事例(画像処理、機械学習、描画、いろんな機能で使ってる)について話すことになるわけで、そうすると、会社に許可を取らないといけない部分も多く、会社にこういう打診をするタイミングももっと遅くなってたかもしれません。そんなキャリアの判断の基準にするほどに、try! Swiftでの登壇は重要視していました。

2018年2月: スライド作成

これは2月中旬に帰国してから着手したのですが、難航しました。「Metalを使うためだけに必要な知識」は本発表のコンセプトでは基本的には不要なのですが、Metalを通じてGPUの気持ちを理解しよう、というところではこの説明をしないといけない、うーむ、みたいな。

同時通訳の方々は下調べ等の準備を行うので、2週間ほど早くトランスクリプトつきで提出する必要があったのですが、まずはできているところだけ提出して順次追加版を提出していきました。

(仙台にてもくもくスライド作成合宿)

2月後半の2週間はほぼフルタイムでtry! Swiftのスライド作成に取り組んでいました。

当日

akatsuki174 がまとめてくれたツイートより、当日の様子が分かる感じのをいくつか時系列にピックアップしていきます。

  • 登壇者としては欠かせない宣伝(英語ですべきだけど)

  • 開始前

  • すごく拡散されていた一枚(スライド全体よりも。。)

  • GPUに向いている処理とは

  • UIImageView vs Metalパフォーマンスの結果発表直前(ちゃんとワクワクしてくれていて嬉しい)

  • 🙏

  • UIImageViewは既に十分に有能だった

  • 問題1

トークの内容としてはまだ続きますが、長くなりそうなのでこのへんで。

反応(ツイート)

これについてはQ&Aで同様の質問をいただいたので、補足記事にてコメントしてあります。

shu223.hatenablog.com

反応(ブログ)

ブログ記事でもいくつか反応をいただいてます。大変ありがたいです。

tech.appbrew.io

GPUがどんな物なのかという導入からMetalを使った自作ライブラリのパフォーマンス測定、その過程で得られた知見についてのトークでした。 MetalとGPUについては知識は殆どなかったのですが、GPUとCPUでのコマンドがどのようにやり取りされているか紹介されていたので処理の概要について知ることができました。 自作ライブラリのパフォーマンス測定ではInstrumentsを使用したデバッグの過程が詳細に述べられており、非常に興味深い内容でした。個人的にはInstrumentsを上手く使いこなせていなかったので、その使用例としても面白い内容でした。 iOSアプリは画像描画の速度でユーザー体験が大きく変わるのでパフォーマンス改善をする際にはMetalの部分まで考慮して実装していきたいです。

medium.com

タイトルに「vs」と入っていますが、実際にはUIImageViewはMetalを使って構築されています。堤さんがUIImageViewのようなものをMetalを使って自作してみようとした経験を元に、Metalが何をやっているのかという部分を通じて、GPUレイヤーに目を向けてみようという話でした。Step by Stepで話が進行してゆき、わかりやすく納得感のある内容でした。

なお、ぼく個人はMetalの知識を全然持っていないのですが、そんな人が興味を持つ導入としての話になっていたのではないかと思います。

blog.lisb.direct

アニメーションなどの描画性能はアプリを作る上で決して無視することができない課題です。このセッションではUIKitの内部処理を理解した上でパフォーマンスチューニングを行うことの大切さを知るための体験談を共有してくれました。directのiOSアプリは短い時間で正確な情報をユーザーに伝えるという大切な使命があります。よりユーザーにとってわかりやすくストレスがないアプリにしていくためにMetalまで意識したパフォーマンスチューニングは大切だと強く意識するきっかけとなりました。UIKitはiOSのバージョンアップによって内部の実装が変わることもあるため、そのバージョンに応じて適切な実装を心がけます。

2018 try! swift - Nakajijapan

これは純粋に面白かったし、Metalのこともわかった気になった。

try! Swift 東京 2018 的一些見聞 - 掃文資訊

カッコ()内はGoogle翻訳

堤修一 以前也是 Kayac 的員工,算起來和我在 Kayac 還有幾面之緣。不過顯然他並不記得我,直到看到我的 badge 的 ID 才説“哦哦,就是那個頭像是小貓的男人啊”。每年 WWDC 結束後其實都會跟着他的 iOS-Sampler 項目學習新 API 的用法,受益匪淺。

(Dian XiuyiはKayacの従業員でもあり、Kayacで私と数えます。 しかし、明らかに彼は私のバッジのIDが「ああ、それはアバターが猫の人だ」と言うまで私を覚えていない。 WWDCが終了してから毎年、彼はiOS-Samplerプロジェクトに従って新しいAPIの使い方を学びます。)

這次他帶來了一個關於 Metal 的話題,探索和對比了使用 Metal 進行圖片渲染和直接使用 UIImageView 的異同。一開始給出的數據十分驚人,Metal 的結果要比 UIImageView 快上十到二十倍。但是隨着深入,發現這不過是測量錯誤和實現錯誤的疊加。實際上按照 WWDC 2017 的説法,UIKit 已經在底層使用了 Metal 進行加速。對於 GPU 相關的性能測量以及中後段通過 Metal System Trace (我自己是從來沒用過) 來尋找問題的部分很有意思。

(今回は、Metalに関するトピックを紹介し、Metalを使用して画像をレンダリングし、UIImageViewを直接使用することの類似点と相違点を調査し、対照しました。 最初に与えられたデータは驚異的でした。メタルの結果はUIImageViewより10〜20倍速かったです。 しかし、深くなっていくにつれて、測定誤差と実装エラーが重なり合っていることがわかりました。 実際、WWDC 2017によれば、UIKitは下部に加速のために金属を使用していました。 興味深いのは、GPU関連のパフォーマンス測定値と、中期および後期のセクションで、Metal System Traceの問題を探す部分(私はそれを自分で使ったことはありません)です。)

一句話總結就是,不要想着從底層折騰一套自己的 UI 渲染了,乖乖滾去用 UIKit 吧。信蘋果,得永生。

(要約すると、独自のUIレンダリングのセットを一から上に投げ捨て、UIKitでロールアウトすることについて考えないでください。 私はリンゴを信じ、永遠の命を持っています。)

https://techblog.istyle.co.jp/2018/03/05/try-swift-2018-report/

try! Swift 2018では普段あまり意識することのないlow-levelに焦点を当てた発表がいくつかあり、そのなかで一番身近に感じた発表がこちらでした。

まず発表自体がとってもわかりやすかったです!!!

また、普段何気なく書いている処理がCPU/GPUどちらで動いているのか、正直気にしたことがなかったぼくにとってはとても新鮮で、新しい気づきとなりました。

こちらは発表が終わった後に質問をしてUITableViewのパフォーマンス改善について有益なアドバイスをいただくことができました。UITableViewのパフォーマンスはほぼ全ての画面で気にしなければいけないことなので、注意していきたいです。

tid-a24.hatenablog.com

GPUのことを考えるきっかけになるセッションでした。 ゲームを作っていたころは、ずっとGPUのこと考えてる状態でしたが最近はあまり考えてません。

  • コマンドを送る時は1回にまとめる。
  • テクスチャはGPUにキャッシュさせる。

などは、基本的にMetalだけでなくOpenGLDirectXでも同じです。

shachi.hatenablog.com

vs とは書いてましたが、内容はMetalで表現すると速い……あれ? なんか変。あ、GPUとCPU切り替えてなかった。ちゃんと区分けしないと。 という「やらないと判らない知見」でした。こういう発表は後に続く人が出るので大変嬉しいし、すてき案件。

medium.com

今回は参加者が理解しやすいような題材としてUIImageView vs Metalという発表をされました。主にMetalを通じてGPUレイヤに目を向けてみようという内容でした。

私達が普段何気なく使っているUIImageViewは早いのでしょうか?ピクセルを配置するなど並列処理可能な処理はGPUに任せた方がよりパフォーマンスが良いのではないでしょうか?

こういった切り口で独自のカスタムクラスを作成し実測値を元に発表されました。

jp.corp-sansan.com

MetalImageViewという、UIImageViewのように画像を扱えるMetalラッパークラスの実装を行った経験を通じて、GPUレイヤーの処理を細かく追っていくという内容でした。XCodeのInstrumentsであるMetal System Traceを効果的に利用してボトルネックを特定し、パフォーマンスチューニングを行っていく過程はとても勉強になるもので、GPUに関する知識が全くない状態でも分かりやすく、大変興味深い内容の発表でした。

After try! Swift

try! Swift 直後の土曜、ワークショップは早退し(すみません)、翌日に日本を発ってしまうFyusion社の同僚たちと東京散策に行ってました。

原宿(同僚たちが既にそこに行ってた)を散策し、カフェで雑談したあと、僕自身も初めてのパチンコ屋に行き、

松阪牛の焼き肉を食べ、ゴールデン街へ。

f:id:shu223:20180317144735j:plain
ゴールデン街(写真は昨年のもの)
バーテンの方に「日本語上手ですね」と言われましたw

おわりに

  • 来年は登壇のプレッシャーもないことだし、もっと海外の人たちにどんどん自分から声をかけてコミュニケーションしたい
  • そろそろSwiftちゃんとやる(仕事ではObjective-C...)

  1. CfPを出して採択されるコースは別として。

  2. 社内に機械学習のプロが何人もいるので。。

try! Swift Tokyo 2018で登壇しました&補足 #tryswiftconf

先週開催されたtry! Swift Tokyo 2018にて登壇させていただきました。

f:id:shu223:20180301180646j:plain

タイトルは "UIImageView vs Metal" ですが、Metalの使い方の話「ではなく」、Metalを通じて普段意識する機会の少ないGPUレイヤに目を向けてみるという内容となっております。

実際のところ多くの開発者にとってMetalは使う予定がない/興味がないもので、この一大イベントで800人もの方々の前で関係のない話をしても仕方がないので、せめて何か興味を持って聞いてもらえる切り口はないだろうか、ということでお話をいただいてからの数ヶ月間悩みに悩み、あれこれ検討して、この方向性で行くことにしました。

というわけでMetalを使ってない、使う予定がないという方々にも多少なりとも興味を持っていただける内容になったのではないかと思います。

日本語版スライドはこちらです。

また、発表で用いた英語版はこちらになります。

補足/FAQ

Metalについて話しつつも主題としては別のところにある、というそもそもの発表の構造と、時間の制約もあり、説明が不十分だった部分もあるのでこちらにて補足させていただきます。

トーク内に出てくる「対策」は必ずしもベストプラクティスではない

トークの中で、「問題1の解決策として2つのコマンドを1つのコマンドバッファにまとめた」というくだりがありますが、注意点として、これはベストプラクティスであるというわけではありません。

(もともとやっていたように)リサイズは先に済ませておいて、draw(in:)では描画処理だけやるのが望ましい、とも考えられますし、そもそも描画処理をMTLBlitCommandEncoderではなくMTLRenderCommandEncoderMTLComputeCommandEncoderでやっていればリサイズ処理を別途やる必要もない(シェーダ内で同等のことをやればよい)とも考えられます。

前者であればではどのようにCPUとGPU間で(お互いを待ち合うことなく)連携するか、という話が必要になってきますし、後者の方向性で実装するのであれば、シェーダ等についての解説も必要ですし、直面する問題も変わってきます。いずれにせよこのトーク全体の構成に大きく影響しますし、シェーダやエンコーダ云々の解説をするのであればトークの主旨すら変わってくるでしょう。

このトークのこのパートで伝えたかったのはあくまで "CPUとGPUの処理フローに配慮する" という「視点」です。

また問題2の対策としてキャッシュする、という話もしましたが、これもキャッシュするべきか否か、どのようにキャッシュするか、というのはアプリケーション次第で変わってくるので、このトークにおいて重要なのはそこではなくて、"GPUからアクセスするリソースの場所に配慮する" という「視点」です。

ごちゃごちゃと書きましたが、つまり、本トークは「このようにしましょう」というベストプラクティスを提示することを意図したものではないので、その点ご留意ください。

最終的な速度はどうなったの?

最終的な処理時間がどうなったかが気になった方は多いと思われます。処理時間ベースで問題提起しておいて改善後のものを出さなかったのには色々と理由がありまして、それらを一言で言うとすると、「今回のトークの範疇では最終結論となるような数値は出せないから」ということになります。

たとえばp38での計測方法の修正によりGPUの処理時間も加味されたものになりましたが、waitUntilCompleted()GPUの処理完了を待って時間を計算している部分はあくまでCPUにおける処理であって、依然として厳密にGPUでの処理完了タイミングを測れているわけではない、というところがあります。

そしてUIImageViewの方は単にCPU側でのメインスレッドにおける処理時間を測っているに過ぎません。これがCPUとGPUの処理フローにおけるどこまでの範囲を測っていることになるのか、それは我々はUIImageViewのソースコードを持っていないのでわかりません1

上記2点の理由により、これら2つの処理時間を並べて比較することが適切ではない、ということがそもそもの話としてあります 2

そして、具体的な数値がスライドの最後に載っていると、その数値がファイナルアンサー(=Metalの速さ)として独り歩きしてしまう恐れがあります3

上記の補足にもあるとおり今回の実装はベストプラクティスというわけでもなく、あくまで概念や視点を伝えるためのものなので、あまり意味のない数値が意味のある数値のように拡散されてしまうのを避けるために、意図的に最終的な数値は明示しませんでした。

ではMetalはどういうときに使うのか?

「UIKitの下回りがMetalになってて、Appleの中の人がしっかり最適化してくれてるので、自分で下手に低レベルAPI触るよりは普通にUIKit使えばいいよ」ということを今回のトークの中で言ったので、じゃあMetalはどういうときに使うのか、という質問をいただきました。

たとえば僕は以下のようなケースでMetalを利用しました。

  • シェーダを書いて独自の画像処理を行う
  • MPSCNNを利用する
  • ARKitのカスタムレンダリング

共通点としては「カスタムな並列処理を行いたい場合」という感じでしょうか。

当然これらの処理のあとに、処理結果の画像をUIImageに変換してUIImageViewで表示する、みたいなことをやるとそれこそまさにトーク内で話した「CPUとGPU間を行ったり来たりする」というバッドプラクティスそのものなので、そのままMetalでレンダリングすることになります。

OpenGLを使っているけどMetalに乗り換えた方がいいのか?

特に具体的に困っていることがないのであれば、乗り換える必要はないと思います。OpenGLの方がクロスプラットフォームですし。WWDCラボでAppleの人が言ってましたが、今のiOSではOpenGLもMetalの上に実装されているそうです。

今から始めるのであれば、Metalの方がOpenGLよりはシンプルでとっつきやすいのでは、と思います。初心者にとっての鬼門はGPUまわりの概念であって、そこさえ押さえてしまえば他方のGPUフレームワークに移るのはそれほど大変じゃない(=つぶしがきく)のではと。

Metalに興味はあるがどこから始めたらよいか?

スライドにもあるとおり、Metalは最小実装でも結構コードが長くなるので、初心者には「はじめの一歩目が遠い」と思います。英語ですが書籍や動画等の学習用リソースは色々とあり、僕も今となってはそれらを参考にしていますが、OpenGLDirectXの経験がない中での最初の一歩目としてはそれらは難しく、結局Appleのサンプルを頼りに四苦八苦して学びました。

で、手前味噌になってしまいますが、僕の昨年のiOSDCでの解説、およびiOS 11 ProgrammingでのMetalの章の解説はそんな「最初の一歩目が大変だった」僕の目線で噛み砕いて書いてあるので、かなりわかりやすいのではないかと自負しております。

ちなみにQ&Aブースで海外の方からこういう質問をいただいて、Xcodeのテンプレート(=比較的最小実装に近い/そのままBuild&Run可能)を色々といじってみるところから始めてはどうか、というアドバイスをしました。僕がそこから始めたので。

MetalImageViewのAPIが途中で変わってる件

p26でmetalImageView.texture = textureという感じで簡単に使えるようにする、と構想を述べつつ、p30ではmetalImageView.textureName = nameとなっていたことに、気付いた人もいたようです。

前者のように構想しつつなぜp30で後者のようにしたかというと、metalImageView.texture = textureとするにはMTLTextureオブジェクトをつくる部分が必要になるのですが、そこをラッパークラスの外に出してしまうとp30のコードが見づらくなってしまうし、MTLTextureに初期化メソッドを生やしてmetalImageView.texture = MTLTexture(named: name)ってできるようにするとコード的には構想通りになるけど、そうするとテクスチャロードが同期的になってしまう(→ その後の話の展開が大きく変わってしまう)、というジレンマにより、こんな感じになりました。

御礼

try! Swiftでの登壇は密かにずっと憧れていました。try! Swiftのフルトーク(↔LT)はCfP制ではなく主催者による招待制なのですが、僕は"Swift力"は並かそれ以下なので、このタイミングでお声がけいただけたのは本当に幸運だったと思います。Metalは、もともと興味があったのはもちろんですが、try! Swiftで話す切り口を模索するために勉強していたところも大いにあります。

結果としては、多くの方に楽しかった、良かったと言っていただき、Q&Aも(僕が閉会式に行き損ねたぐらいに)途切れることなく質問に来ていただきました。

出番が最後の方だったこともありずっと気持ちがフワフワしていましたが、非常に思い出深い3日間でした。

長期間準備され、会期中は朝早くから夜遅くまで動き回っていたスタッフの皆様、スポンサー企業の皆様、参加された皆様、どうもありがとうございました!Swiftもっと勉強します。


  1. 今年WWDCに行けたらラボで聞いてみます。

  2. ではなぜ最初にこれらの比較を行っていたかというと、計測方法において僕が実際にしていた勘違いを紹介し、その改善の流れを見ていただくことがGPUレイヤへの「視点」を理解するのに役立つと思ったからです。

  3. BLEのときにそういうことが実際にあった

パートタイムになりました

2016年10月よりサンフランシスコのFyusion社でフルタイムで働いてきましたが、今年2月16日より、パートタイム社員として働くことになりました。

・・・とだけ書くと、あれ、fire的な何か?と心配されそうですが、これは僕から希望して、どちらかというと会社に無理を聞いてもらったかたちになります。

どうなったかシンプルにいうと、今後はアメリカにいる間は会社にフルコミット、日本にいる間はフリー」ということになりました。H-1Bビザはフルタイムである必要はないので、今後も維持されます。1

Fyusion社で、サンフランシスコで働くことは学びが多く、メンバーも魅力的な人達ばかりで、まだまだ続けたい気持ちがありつつも、興味のある技術を勉強し、発信し、そこから仕事を獲得し、さらに経験と実績を積み・・・というフリーランス時のサイクルが恋しくもあり、フルタイムで働くことに悶々とするところもありました。

で、今年の年明け早々に長い長いメールを書いて自分の考えを伝え、僕の希望と会社の要望との摺り合わせ、法務・労務的な調整etcがあって、このような形となりました。こういうわがままを受け入れてくれた会社の皆様には本当に感謝です。より濃い密度で貢献していく所存です。

アメリカと日本にいる割合ですが、1:2ということで今は考えています。3分の2はまた以前のようにフリーランスとなりますので、みなさままたよろしくお願いいたします🙇🏻

関連記事

入社の経緯と経過報告

d.hatena.ne.jp

d.hatena.ne.jp

結局どうしたいの、というあたりのキャリア観については以下の記事に書いています。

d.hatena.ne.jp


  1. 確定申告はアメリカと日本、両方でやることになります。

移転しました

これまで書いていた「Over&Out その後」から移転しました。

d.hatena.ne.jp

さらにその前身として、「Over&Out」というブログがあり、2010年のキャリアの節目をもって「〜その後」に移行したのですが、そちらももう7年も書いてきて、はてなダイアリーも「ネット界の限界集落」なんて言われたりして、そろそろはてなブログに移行しようかなと思っていたのと、ちょうどいま、また自分のキャリアの節目感がある(後で記事を書きます)ので、移転に踏み切りました。

過去記事をインポートすることも考えたのですが、リフレッシュしたかったのと、古い記事が古い場所にそのままあるのもいいかなと思いまして、とりあえずそのままにしておきました。

前身ブログの主な記事

とはいえキャリアのこととか、考え方とか、そういうものは地続きなので、こちらにいくつか主な記事のリンクを貼っておきます。

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

d.hatena.ne.jp

3D写真の機能をアプリに組み込める「Fyuse SDK」の使い方


Fyuse SDKを使うと、3D写真(=Fyuse)を撮る/見る機能をアプリに組み込むことができます。



本記事ではそんなSDKの使いどころや組み込み方法について紹介してみたいと思います。 ※念のため、このFyuseおよびFyuse SDKは、僕が所属しているFyusion社のプロダクトです。


ちなみに僕はiOSエンジニアなのでiOSの実装を紹介しますが、我々のSDKはiOS, Android, Webをサポートしています。

Fyuseとは

我々の3D写真フォーマット「Fyuse」は、静止画とも動画ともポリゴンベースの3Dモデルとも違うものです。App Storeにある同名のアプリでどんな感じかお試しいただくことができます。



例として、僕はこんな場面でFyuseを撮ってます。※はてなダイアリーの制約で、ビューアを埋め込むことができなかったので、アニメーションGIFに変換して載せています。ぜひリンクから、Fyuseビューワで見てみてください。

(とある街の道端にあった牛の像)


普通の写真だと、片面だけとか、前からだけになりますが、Fyuseでは立体物をマルチアングルで記録できます。



Fyuseアプリのタイムラインを見ていると、

  • 人(ファッション・コスプレ)
  • 像、彫刻、フィギュア、プラモデル
  • 壮大な景色

あたりはFyuseフォーマットが非常にマッチするなぁと思います。僕は普通に記録フォーマットのいち選択肢として日常使いしてます。

SDK導入事例

モノをいろんな角度から見れる、というところからEC系とは非常に相性が良く、車業界、ファッション業界、大手総合ECサイト等ですでにご愛顧いただいてます。


公開OKを確認できた国内事例ですと、"d fashion"さんの360°アングルでのコーディネート紹介ページがあります。


また中古車販売のガリバーさんにご利用いただいております。


「車」向けのFyuseについては会社のサイトでも詳しく紹介されてるのでぜひ見てみてください。

SDKの使い方:Fyuseを「撮影する」機能を組み込む

Fyuseを撮影する機能の実装は、Fyuse用のカメラを起動する → 撮影を開始する → 保存する という流れになります。

カメラの起動

1. `FYCamera`オブジェクトを作成する

private let camera = FYCamera()


2. `prepare`して、`startPreview`する

camera.prepare()
camera.startPreview(with: previewLayer)

`startPreview`には`AVCaptureVideoPreviewLayer`オブジェクトを渡します。

これでFyuse撮影準備完了です。

撮影開始/停止

それぞれメソッドを1つ呼ぶだけです。

camera.startRecording()
camera.stopRecording()
保存

撮影したFyuseをローカルに保存するにあたって、まずは撮影の完了イベントを受けるために`FYCaptureEventListener`プロトコルへの準拠を宣言しておき、

class ViewController: UIViewController, FYCaptureEventListener

FYCameraのリスナーとして追加しておきます。

camera.add(self)


すると、撮影中・完了時・失敗時に`fyuseCamera(_:captureEvent:)`が呼ばれるようになります。

func fyuseCamera(_ camera: FYCamera, captureEvent event: FYCaptureEvent) {
    switch event.captureStatus {
    case .inProgress:
        // 撮影中
    case .completed:
        // 撮影完了
    case .failed:
        // 撮影失敗
    }
}


ここで、保存する際には内部的に様々な処理を行うため、それらを非同期で実行するクラス`FYProcessingQueue()`を使用します。

private let processingQueue = FYProcessingQueue()!
processingQueue.processEntry(path) { 
    print("Fyuse is saved at \(path)")
}

これで撮影機能は完成。


SDKの使い方:Fyuseを「見る」機能を組み込む

基本的にはたったの2ステップ

  • 1. FYFyuseViewオブジェクトを作成する
@IBOutlet private weak var fyuseView: FYFyuseView!

ちなみにIBを使用せず次のようにコードから初期化してaddSubviewしてもokです。

private let fyuseView = FYFyuseView()
  • 2. 表示したいFyuseを`FYFyuse`オブジェクトとして1に渡す

`FYFyuse`オブジェクトは、先ほど`FYProcessingQueue()`で処理・保存した際に取得したパスを渡して初期化します。

fyuseView.fyuse = FYFyuse(filePath: path)

これだけです。

先ほど撮ったFyuseがインタラクティブに閲覧できるようになります。


More

基本機能の実装方法を解説しましたが、Fyuseは「撮る」「見る」だけでなくいろいろと機能を持ってまして、たとえば以下のようなものがあります。

Visual Search

3Dベースのディープラーニングを用いた物体検索

Car Mode

車をあらゆる角度からオンデバイスで認識し、きれいに車のFyuseを取れるようにする

Tagging

Fyuse同士をタグ付けで関連付けられる。

  • 車全体のFyuseのタイヤ部分に、タイヤにフォーカスして撮ったFyuseを関連付けたり

VR, AR & MR-ready

Fyuseで撮った人物や車等をVR/AR/MR環境にエクスポート可能


(Fyuseの人物の背景を変え、エフェクトを載せるデモ)

Infinite Smoothness

空間内におけるフレーム間を動的に補完してスムーズに表示

  • この技術のおかげでファイルサイズは〜5MBと、非常に小さく済む

お問い合わせください

Fyuse SDKをサイトからダウンロードできるようにするのはまだ準備中です。気になった方はぜひお問い合わせください。

お問合わせは日本語でも可です。


ちなみに、今月(2018年2月)はエンジニアリングのトップと、ビジネスデベロップメント/マーケティングのトップが日本に行くので、直接ミーティングできると話も早いと思います。ぜひぜひこの機会に!


2017年の反省


ふりかえり的なことは先月に書いたのですが、

実際のところこの記事は上澄みだけすくい取ったようなもので、ここには書いていない反省や葛藤がたくさんあります。


いま12月31日ですが、その葛藤はいまも現在進行系で自分の中にあるなーという気がするので、やはり2017年の振り返りというか主に反省を書いておきたいと思います。

反省1: アウトプットが減った

技術記事をあまり書かなかった

自分のブログ(これ)はほとんど「◯◯しました」系の自己PR記事だけになり、Qiitaでも(この12月のアドベントカレンダーの時期を除き)ほとんど記事を書いていませんでした


フリーランス時代は仕事を減らしてでも勉強時間を確保し、勉強したことをアウトプットしていましたが、会社員になると週5日が自動的に埋まってしまいますし、発信することへの意識もだいぶ下がってしまった*1感があります。

iOS 11 Samplerを出さなかった

iOS 7のころから4年続けていたiOS Samplerシリーズ、今年はついにサボってしまいました。


例年8月ぐらいから始めて、そこそこ時間をかけて実装して、9月の正式リリースに合わせて公開、というスケジュール感なのですが、今年のその時期はiOS 11 Programmingの執筆で手一杯で、まったく無理でした。


せめてもの足掻きとして(成果物の横展開的な発想で)ARKit-Samplerを公開しましたが、それもサンプル数がちょっとしかなく、追加更新もできず、例年とは大違いです。*2


iOS Samplerはそもそも「自分で新APIを使ってみて、どんなもんか把握しておく」という目的で始めたもので、今年はiOS 11 Samplerをつくってないので、iOS 11の新機能があまり(実感として)把握できてないという普通に宜しくない状況です。

反省2: 「自分にとって唯一の技術スタック」で遅れをとってきている

「最近のiOS開発」がキャッチアップできてない

会社ではSwift書いてませんし、新しい技術の勉強としても、機械学習とかMetalとか3Dまわりをやってたので、

こういうあたりが全然キャッチアップできてません。ずっとiOSしかやってないエンジニアが、そのiOSでもメインストリームから遅れをとっている感。焦りがあります。

アプリ開発に対して腰が重くなった

ちょっと前までは、「iOSアプリをゼロから実装して、申請して、ストアに出す」という一連の流れは「簡単」という感覚だった気がするのですが、今ではすっかり腰が重くなり、既存アプリをアップデートするにしても、非常に大変な作業のように感じてしまいます。


経験を積んで作業の見通しがより正確にできるようになった(ので、大変に感じる)という面もあるかもしれませんが、割り切りが下手になった、頭でっかちになってしまった、という面が大きいように思います。


また、前述した、最近のベストプラクティスについてキャッチアップできてない、というところもあると思います。


自分はそもそもアイデアを形にするところが楽しくてiOSをやってきたので、アプリ開発へのフットワークの軽さは取り戻したいところです。

反省3: アメリカで働いてるのに、アメリカで勝負してない

僕は元来保守的で、不安やプレッシャーを過度に抱えたくないので、1つの重要なチャレンジをしているときは他のチャレンジは諦めてよい、と自分を赦すところがあります。


で、2017年は

  • 今は英語よりも新しい技術(Metalや機械学習)を勉強するのが重要
  • いまはとにかく本の執筆(iOS 11 Programming)が最重要

みたいな状況が続き、英語とか、アメリカ社会にあまりまともに向き合っていない1年でした。


具体的には、

  • 会社が健康保険も負担してくれてるのに、なんだかよくわからないし調べるのも面倒だから日本に帰ったときに病院行こう
  • そろそろクレジットヒストリーがたまって条件の良いカードをつくれそうだけど調べるのが面倒だから最初につくった日系企業のカードをずっと使ってる

とか、諸々そういう話。


あと、こうして日本語での発信を続けているのもそうだし、未だに会議で全然みんなが何言ってるのかわからない程度の英語力を放置しているのもそう。


同じ時期にサンフランシスコの会社に就職し、グリーンカード取得を見据えて働いている友人等を見ていると、しっかりアメリカと向き合って暮らしているな、と思います。「海外で暮らす」ということに伴う様々な困難に対して、彼らはしっかり向き合い、乗り越えている。僕はただ避けているだけ。せっかく海外で働いているのに、これでは世界が広がっていかない

総括

2017年の反省点をつらつらと書きました。単純に心構えや時間の使い方を改善するだけで対策できそうなところもありますが、これらの根底には、会社員とフリーランス、アメリカと日本、というところでの自分の中での葛藤、あるいは切り替えの中途半端さがあるように思います。そういうフワフワしたところのせいで、この1年の4分の3ぐらいは有意義だったものの、残り4分の1ぐらいはなんだか中途半端に過ごしてしまったような。2018年はこのへんの問題にちゃんと向き合い、優先度をしっかりもって行動したい所存です。


*1:仕事の依頼が来ても基本的には受けられないので。

*2:iOS Samplerシリーズは、だいたい公開時からサンプル数が20前後ありますが、それはたまたまではなくて、意識してそこまで持っていってます。(数の)驚きがないと、広がっていかないので。