iOS で SceneKit を試す(Swift 3) その3 - 3DCG の軽い説明
3DCG は現実空間と同じように3次元なので、
映画を撮るのと同じように、表示する対象物、それを撮るカメラ、
対象物をカメラから見えるようにするライトがあって初めて映像が完成する。
まとめると 3DCG を表現するには最低でもこの3つが必要
- カメラ
- ライト
- オブジェクト/ジオメトリ (表示する対象物)
オブジェクトは CG の用語でマテリアルと呼ばれるものを設定し質感ができる。
よくゲームとかでテクスチャ(画像)と呼ばれるものはマテリアルに画像を貼り付けている。
球体のマテリアルに色をつけたもの | 球体のマテリアルにテクスチャをつけたもの |
---|---|
それと、SceneKit は Y 軸が上を向く右手系の座標です、
奥行きが Z 軸で手前がプラスになってる。
Apple Developer サイト API Reference - SceneKit のページから転載
今回はここまで。
iOS で SceneKit を試す(Swift 3) その2 - SceneKit の中身
iOS の描画はざっくり説明すると、
3D 描画のライブラリの上に Core Graphic や Core Animation などが使用され表示しアプリの見た目ができている。
以下、WWDC 2015 の資料より抜粋し修正。
3DCG を描画する SceneKit の中身は、
Core Graphic と並列処理を行う SIMD の命令、
ローレベルの API のいずれかと、
サービスの Model I/O でできている。
APIの説明
ローレベル API
名称 | 説明 |
---|---|
Metal (MetalKit) | Apple 版 DirectX。 Apple 製品でしか動かないためハードとのオーバーヘッドが少なく、CPU オーバーヘッドを少なく設計され、CPUとGPUでメモリが共有が行われている。 C++11 ベースの Metal シェーダーは事前コンパイルされて実行される。GLSL も変換して使用することもできるらしい。 |
OpenGL(ES) | 汎用 3DCG ライブラリ。Metal 比べて処理が大幅に遅い。Android で Valkun という Metal に近いものが使えるようになったため、使用されるケースが減る可能性もある。 |
サービス
名称 | 説明 |
---|---|
Model I/O | 3D オブジェクト、そのマテリアルやテクスチャの入出力。 ライト、テクスチャへのライトの描画など処理ができるライブラリ。 |
GameController | 対応しているゲームコントローラーの操作を使用できるようにするライブラリ。iOS の場合ゲームコントローラー必須にした場合審査に落ちる。 |
ReplayKit | iOS 操作中の音や映像をキャプチャできる。iOS 10 から Periscope などのライブ動画アプリ経由で配信できる。 |
GamePlayKit | Min-Max などゲームに使用する AI、経路探索、乱数、指定した物体に追従するエージェント、ステートマシン、コンポーネント化などゲーム開発をサポートする。 |
ハイレベル API
名称 | 説明 |
---|---|
SceneKit | 3DCG ライブラリ。今後説明するので割愛 |
SpriteKit | SceneKit の 2DCG 版。SceneKit の同様の機能と、連番のテクスチャアニメーション、2D の物理アニメーション、画像をタイル状に配置してマップ作成などができる。 |
今回はここまで。
iOS で SceneKit を試す(Swift 3) その1 - はじめに
もしかして、WWDC 2017 で AR 的なものが出るかもしれないので勉強ついでのメモ書き。
専用のフレームワークが用意される可能性が高いけど。
あと、WWDC の動画からの抜粋なので英語がわかる方はこちらを見た方が良い。
https://developer.apple.com/search/?type=Videos&q=SceneKit
SceneKit とは
SceneKit は iPhone, iPad, iPod Touch などの iOS、
Apple Watch の watchOS、
Apple TV の tvOS、
Mac などの macOS で使用できる 3DCG ライブラリ。
簡単に説明すると使いづらい Unity。
SceneKit での利点は、直接 Swift や Objective-C で動いているため、ネイティブ命令との親和性が高く、SceneKit の View の上に iOS の UIを配置する事が可能。
また、現状 Unity の Editor では Exstentions を作成できないため、watchOS のアプリがそのままつくる事ができない。
watchOS のアプリを 3D でつくる必要性があるかはあれだけど。
SceneKit でできる事
- モーフィングアニメーション
- ボーン/スキニングアニメーション(IK 可)
- 位置、ルックアップ、IK などのコンストレイント (制限)
- 物理アニメーション
- SceneKit で用意されたアニメーション機能
- パーティクル
- ヒンジ/ボール/スライドジョイントアニメーション
- 車を模した物理アニメーション
- 物理ベースのシェーディング
- マテリアルに SpriteKit や CALayer の適応
- オブジェクトへのフィルター適応 (Core Image - CIFilters)
- カスタムの Metal シェーダー
- オブジェクトへ陰を落とす
(初回描画のみ、ライトで動的に変化、ゲームでよくある画像の陰) - オブジェクトのヒットテスト
- OpenSubdiv
- Level Of Detail
- 被写界深度
- Fog
- 複数のカメラ配置と切り替え
- IES ライトなど物理ベースのライティング
- アンビエントオクルージョン
- グローバルイルミネーション
- 画面全体のマルチパスエフェクト
- 画面表示に SpriteKit のオーバーレイ(HUD 用)
- オーディオ再生 (3D 音響)
- シーンのノード階層の平滑化 (パフォーマンス向上の施策)
- JavaScript ブリッジ
- Xcode でタイムラインエディタを使用したアニメーション編集
- Xcode でのパーティクルアニメーション編集
など
ひとまず動かす
Xcode を起動。
Create New Project (command + Shift + N) でプロジェクト作成
iOS の「Game」を選択して「Next」ボタンを押す。
Product Name に適当な名前をつけて、
Game Technology のセレクタから「SceneKit」を選択して、「Next」ボタンを押す。
ビルド(command + R) でシミュレーターか実機にビルドされる。
スペースシャトル的なものが表示され、タップやピンチで画面操作可能。
iOS シミュレーターでは処理落ちするかもしれないが、実機では 60 fps で滑らかに表示される。
もし早く表示を確かめたいのであれば、macOS のアプリとしてビルドした方が良いかもしれない。
また、iOS シミュレーターでは現状では Metal が動作しない。
macOS、tvOS でも動かす
プロジェクト作成時に、macOS か tvOS を選ぶだけであとは同じ。
今後、iOS、macOS、tvOS、watchOS を1つのプロジェクトの動作する方法を書くかも。
画面下の統計情報の軽い説明
- 詳細表示用の「+」ボタン
- フレームレート(ゲージ)
- 使用しているライブラリ名 OpenGL(ES) or Metal
- プレームレート(文字)
- ドローコール(フレーム毎)
- 表示全体のポリゴン数
「+」ボタンの内容に関してはプラットフォームごとに異なるのでまた後で。
フレームレートは 60 fps 以上を最良としており、ゲージが緑色である事が望まれる。(40 fps ぐらい?)
ライブラリの選択はデフォルトだと自動になっているが、Metal Shader を使用する際は GL ではなく Mt と表示されていなければ動かないので注意。
ドローコールは描画するものが画面に現れると1カウントされ、
その隣は画面上のポリゴン数。
フレームレートのゲージが描画されるとドローコールが1、ポリゴンが38増える。
そのため、このプロジェクトをビルドすると
- フレームレートのゲージで 1
- 宇宙船で 1
合計 2 のドローコールが走る。
ドローコールが無駄に多い場合は効率的に表示されていない可能性がある。
今回はここまで。
WWDC 2017 で発表されたらいいなと思う開発者向けの機能、ハード、サービス
ソフト面
- iSight Duo からの深度情報取得
- 深度情報取得からの AR
- カメラ画像と深度情報取得からの物体認識
- 3D の航空写真地図から建物 3D オブジェクトの取得
- iOS の UI の刷新
(もしするなら tvOS の様になりそう) - iOS の UI でダークテーマ
- iOS で tvOS のようにパララックスで表示されるアプリアイコン
- グラフなど統計用の UI
(Numbers の UI を全般的に使いたい) - NFC の使用制限緩和
(NFCカードへの読み書きとかやりたい) - 横方向の移動を設定できる UITableView
- バックグラウンドで使用できる機能の追加
- Message アプリ用 Bot 開発
- Siri の開発者が操作できる範囲の増加
- Proactive Assistant の適用範囲強化
- 端末内部での検索機能強化
- Metal を使用したの行列計算や機械学習用ライブラリ
- SQLite に変わる独自データベースの実装
(FoundationDB を買収しているため) - 買収した Workflow アプリがシステムに統合され開発者側が単機能のアクションを制作できる
- 時計アプリのアラーム設定情報取得
- iSight Duo or カメラからの 3DCG 用オブジェクトの作成(6/5 追記)
- tvOS で iPad の様なスプリットビュー と ピクチャー・イン・ピクチャー
- iOS 版の Instant Apps
- iOS 版の Safari Technology Preview
- Windows 10 Fall Creators Update のタイムライン機能
ハード面
- iPhone / iPad 版 Touch Bar
- Bluetooth 5.0 とそれを使用した高音質オーディオ伝送
- 機能を付加した Apple Watch のバンド(噂では血糖値の測定)
- リビングを牛耳る Siri 端末
多分、Apple TV にスピーカーがついたものか、Apple TV と連携するスピーカーだと思われ - iOS、macOS、tvOS で使用できる新たなポインティングデバイス
- HomeKit デバイスとして簡単に機器を拡張できるデバイス
サービス
- 動画の定額配信
- CloudKit を拡張した Apple 版 Firebase
- CareKit、ResearchKit からの個人用医療カルテと医師や病院とのマッチング
夢
- AR 眼鏡
- iOS、macOS、tvOS での UI 統一(6/5 追記)
- iOS 版 Logic Pro、Final Cut Pro
- iOS 版 Xcode
- Apple 謹製 3DCG 作成アプリ
- SpriteKit、SceneKit での Cloth、Fluid シミュレータ(6/5 追記)
- macOS で iOS アプリの起動
- ARM 版 macOS
- Apple TV のデスクトップ PC 化
- Apple TV のサーバー 化
- 高機能な Hearable 端末
- Surface Pro 4 で使用されているタイプの顔認識ログイン
- iPhone / iPad から Bluetooth ヘッドフォンなどのアクセサリーへの充電
- iOS 実機でしか確かめられない機能があるので、macOS の iOS Simulator でも操作しする様にしてほしい
P.S. やってほしいこと
個人的には Xcode の SceneKit の Scene Editor を Unity の Editor に近しいぐらいまでしてほしい。
Unity から作成される iOS アプリの最適化があまりよろしくないため、ネイティブでつくりたい。
あと、FBX ファイルを読み込めるようにしてほしい。
Blender からエクスポートされる Collada(.dae) の情報でシェイプキーなど Xcode で全て取得できないため。
Apple Watch の デジタルクラウンで寿司を回す
今回は Touch Bar のやつよりも簡単なので、
寿司を回す職人の方は試してみてはいかがでしょうか。
私、Apple Watch 持っていない貧民ですので Sumilator 上でしか試していません。
実機で動かなかった場合はごめんなさい。
ちなみに Sumilator 上でデジタルクラウンを試す場合はマウスのホイールか、トラックパッドで二本指スワイプをしましょう。
1. Xcode 8.3.2 でプロジェクトを作る
Extension からやるとスクリーショット撮るのが面倒なので
Cross-Platform の SpriteKit でプロジェクトを作ります。
今回は「SushiWatch」というプロジェクト名にしました。
2. SpriteKit の watchOS 用の Scene を修正する
SpriteKit の Scene に関する動作は GameScene.swift にあります。
58 〜 64 行目にテンプレートで watchOS の記述がありますが必要ないので消します。
代わりに以下の命令を書きます。
label?.text = "🍣" label?.fontSize = 500
ビルドする項目を iPhone と watchOS シミュレーターにしてビルド。
美味しそうな寿司が表示されます。
3. SpriteKit の Scene へ寿司を回すメソッドを追加する
以下の1秒で r 分回る命令を適当なところに入れます。
func rotateText(_ r:Float){ self.label?.run( SKAction.rotate(byAngle: CGFloat(r), duration: 1) ) }
試しに初期化のところに回転の関数を入れてみましょう
label?.text = "🍣" label?.fontSize = 500 self.rotateText(1)
寿司がラジアンの 1 の値で回ります。
回転が確認できたら self.rotateText(1) は消しても大丈夫です。
4. Extension 側にメソッドを追加する
- デジタルクラウンのデリゲートを設定
- watchOS の Extension に Scene を呼び出し
- デジタルクラウンの初期化と操作を呼び出し
- デジタルクラウンのデリゲートの内容を設定
InterfaceController.swift を開き、デジタルクラウン使用するためのデリゲートを追加。
class InterfaceController: WKInterfaceController, WKCrownDelegate { ... }
使い回せるように変数として Scene 呼び出し
private var scene:GameScene!
override func awake() 内に初期化を focus で操作の呼び出し
let sequencer = self.crownSequencer sequencer.delegate = self sequencer.focus()
以下のデジタルクラウンのデリゲート内容を設定。内容は scene で設定したメソッドを呼び出しているだけの簡単なものです。
あとはビルドするだけです。
func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) { scene.rotateText(Float(rotationalDelta)) print("DigitalCrowm - Delta:\(rotationalDelta) PerSecond:\(self.crownSequencer.rotationsPerSecond)") } func crownDidBecomeIdle(_: WKCrownSequencer?) { print("デジタルクラウンが止まりました") }
crownDidBecomeIdle は止まった時に呼ばれます。 必要なければ消してください
InterfaceController.swift の全コード
import WatchKit import Foundation class InterfaceController: WKInterfaceController, WKCrownDelegate { @IBOutlet var skInterface: WKInterfaceSKScene! private var scene:GameScene! override func awake(withContext context: Any?) { super.awake(withContext: context) scene = GameScene.newGameScene() // Present the scene self.skInterface.presentScene(scene) // Use a preferredFramesPerSecond that will maintain consistent frame rate self.skInterface.preferredFramesPerSecond = 30 let sequencer = self.crownSequencer sequencer.delegate = self sequencer.focus() } override func willActivate() { // This method is called when watch view controller is about to be visible to user super.willActivate() } override func didDeactivate() { // This method is called when watch view controller is no longer visible super.didDeactivate() } // Digital Crown Delegate func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) { scene.rotateText(Float(rotationalDelta)) print("DigitalCrowm - Delta:\(rotationalDelta) PerSecond:\(self.crownSequencer.rotationsPerSecond)") } func crownDidBecomeIdle(_: WKCrownSequencer?) { print("デジタルクラウンが止まりました") } }
まとめ
基本的にはデリゲートの設定だけで、
デジタルクラウンを回して反応するコードが簡単にかけます。
皆様もいろいろなものをデジタルクラウンで回してみてはいかがでしようか。
デバイスはマテリアルにこだわり始める時代
デバイスのデザインに関してはセンサーやバッテリーなどハードの問題もあり、
完成系となりつつあるため、デバイスやガジェットは素材にこだわる形でデザインの提供を行うのではないかと感じている。
自分の中で印象深かったのは au design project から吉岡徳仁氏のデザインで世に出た MEDIA SKIN。
シリコン粒子を配合した塗料や一部色では特殊ウレタン粒子を含んだボティをでつくられ、細かな隆起が施してあり、
今まではプラスチックや金属であったものとは違う手触り感を与えた。
ちなみに世界で初めて有機ELディスプレイを採用を端末である。
他のフィーチャーフォンでは NTT DOCOMO から TOUCH WOOD という本体が木でできたものもある。
フィーチャーフォンの後半ではマテリアルにこだわったもがいくつかあった。
このような流れを踏襲するわかりやすい端末は NuAns NEO だろう。
ボディを上下のカバーを変更可能で、MEDIA SKIN や TOUCH WOOD のように
スエードやデニムや革などの服地使用されるものや
木、特殊素材なのでボディに質感をもたせている。
https://neo.nuans.jp/reloaded/
また、VR ヘッドセットは従来プラスチックのものがほとんどではあったが
Daydream View はファブリックを使用している。
https://vr.google.com/daydream/smartphonevr/
Apple Watch のバンドもいくつかの素材を提供している。
Apple も肌に接する手触り部分はバリエージョンを必要としたようだ。
ハーローの実験では「愛着はミルクだけで生まれるのではなく、接触の快適さがなににもまして重要」という結論を得た。
ウェアラブルに近しい端末は今後マテリアルにこだわる方向性なのかもしれない。
iOS と App Extension、そこにつながるデバイス
iOS のアプリは、
基本的には異なるアプリとの同士では会話ができない隔離されたシステムで運用されている。
macOS では LION ぐらいの頃 XPC Service というものが出て、アプリ間での通信ができたわけだが、
iOS の XPC はプライベートフレームワークとなっており、
ストアに申請する事はできず使用できなかった。
そこで、歳月が経ち出現したのは App Extension。
文字どうりアプリの拡張機能である。
拡張機能は、アプリ本体とは別のプログラムファイルで、
開発したアプリと他のアプリをつなげるものだったり、
カスタムキーボードなどシステムに紐付いているものがある。
(ステッカーパック、いわゆるスタンプは Message アプリに紐付いており、本体アプリは必要ない。ずるい)
別のプログラムファイルという事でわかるかもしれないが、 本体のアプリとは別の環境で動き、実は互いには直接アクセスはできなく、OS が間に入る。
そして、OS はアプリと拡張機能のアプリが同じグループ内いる場合、他のアプリが入れない部屋をつくり、そこを通じてデータを操作できるようにする。
このことによって、アプリは拡張機能を通じて安全なデータの受け渡しができたりしている。
一応、2017年4月の時点で作ることのできる拡張機能
(時間があったら下の詳細を書くかも?)
ここにはないが、WatchKit App(watchOS)と watchOS の Game 用の 拡張機能がある。
要するに、App ストアに並んでいる
Apple Watch のアプリは拡張機能で実装されている。
同じアプリでデバイス間でデータアクセスするとなると、拡張機能で作成するのが現状もっとも適しているからだろう。
今後、もし新しいデバイスが増えるなら、噂されている AR 的のものやデバイスが実装されるのなら、
そこには App Extension が使用されるだろう。
あ、ちなみに、 Unity など Xcode のプロジェクトファイルを直接いじれない、
ほとんどのマルチプラットフォーム開発では
App Extension が簡単に開発ができなかったりする。