catalinaの備忘録スマートフォン用の表示で見るcatalinaの備忘録ソフトウェアやハードウェアの備忘録。後で逆引きできるように。VisualStudio2015アプリをごりごり作るよりも前にデバッグ情報などを実機で見やすくする仕組みをつくりました。従来手法のビルボードはHoloLensではそのまま使うのは少し難ありです。HoloLensが提供している機能を使ってビルボードをレンダリングするのが良い。ビルボードって?この用語が本当に正しいのかどうか疑問ではありますが、概要だけ。一言で言うなら「常にカメラのほうを向くポリゴン」です。いうところで使うの?3Dのゲームを遊んだことがある人なら一度は見かけたことがあると思います。「常にカメラのほうを向いていなければいけない」ポリゴンというのは多々あって、例えば次のようなものが考えられます。MMORPGなどでのキャラクタ名、ダメージ数字の表示、メニュー、ツールバーなどFPSの照準アイコンポイントスプライト(パーティクル)これらは一枚の板ポリゴンにテクスチャを張って、そのポリゴンが必ずカメラのほうを向くように設定することで実現できます。やって実現するの?カメラのほうを向くポリゴンを作る方法は、まず最も単純な方法としてはカメラ座標系でX,Y平面にポリゴンを書くだけで実現できると思います。先の例でのメニューやツールバーなどはこれで解決ですが、応用してパーティクルを使った演出をする場合にちょっと不便で汎用性に欠けます。いうのもパーティクルはワールド空間上の特定の位置に配置されるオブジェクト(火の粉だったり、煙だったりのエフェクト)であるので、ワールド座標系で指定したいものです。して考えると、カメラ座標系で直接ポリゴンを描くのではなく、ワールド座標系で座標を指定したうえでポリゴンが常にカメラのほうを向くようにしたいです。3Dゲームなんか向けのサイトを見てみると、カメラの回転行列からの逆行列をオブジェクトの行列の回転行列成分にセットするという方法が一般的のようです。いうわけで、HoloLensのカメラ行列からビルボードを作れないか試してみます。HoloLensのレンダリングパイプラインカメラ行列からの逆行列を求めてそれを使うというアプローチですが、HoloLensで同様の手法を使うことはできなさそうです。3Dモデルをレンダリングするとき、のカメラ行列の設定ですが、VisualStudioが生成するスケルトンではこうなっていました。bufferを参照するHLSLシェーダはこうなっています。(min16float4)pos;何やってるのかの前にAR/VRの基本的な話です。HMDを使って3Dレンダリングするとき、左右のレンズに少しだけ異なる映像を出すことで立体感を出すという手法があります。人間の目が少し離れた位置についていて~と話が長くなりそうなので、ここでは「そういう手法がある」程度にとどめておきます。HoloLensも同じ理屈で、左右のレンズに同じものをレンダリングしているわけではなく、左レンズ用と右レンズ用の映像をレンダリングします。HolographicStereoTransformというクラスが左レンズと右レンズそれぞれの透視投影変換とビュー行列をもっているので、これを引っ張ってくるわけですね。それぞれのレンズ用にレンダリングするためにDrawIndexedInstancedを使って左レンズ用インスタンスと右レンズ用インスタンスでレンダリングします。テンプレートプロジェクトではシェーダーの入力パラメータにinstIdというのがいますが、これがインスタンスのIDというわけですね。Docsなので、従来手法の「カメラの回転要素の逆行列を3Dモデルの回転行列に使う」というアプローチをそのまま流用しようとしても、モデルの回転行列を左右レンズそれぞれに生成する必要があって、それはあんまりです。HoloLensの座標系で考えるそもそもHoloLensではスクリーン中央に常にカーソルがレンダリングされています。このカーソルは視線の先の空間マッピングされたオブジェクト上に出るのですが、これと同じことができればいいわけです。公式マニュアルに座標系のことが書いてありました。cameraこれを真似していけば良さそうです。絶対座標と相対座標というと誤解しそうですが、概念として絶対座標:空間マッピングしたワールド空間上の座標を表す相対座標:デバイスそのものからの座標を表すと解釈できます。HoloLensのプロモーションなどで空間上に何かのオブジェクトを配置しているケースでは上記の絶対座標を用います。相対座標はドラゴンボールのスカウターや名探偵コナンの探偵メガネのように装着者からみた座標系として考えられます。デバイス相対座標を取得するまず、VisualStudioのHoloLensテンプレートプロジェクトでは、座標系として絶対座標(ワールド座標系)を使っています。Windows::Perception::Spatial::SpatialStationaryFrameOfReferenceがそれです。上記リンク先の記事を読みつつ、相対座標系に置き換えます。Windows::Perception::Spatial::SpatialLocatorAttachedFrameOfReferenceがデバイスからの相対座標を扱うための参照です。型を置き換えてもこのままではインタフェースが違うのでうまくいきません。SpatialLocatorAttachedFrameOfReferenceでSpatialCoordinateSystem^を拾うにはGetStationaryCoordinateSystemAtTimestamp(prediction->Timestamp);とします。HoloLensの姿勢を取得するこれでHoloLensの相対座標系で色々できるようになりました。prediction->Timestamp);で拾えます。公式マニュアルはこちら。DocspointerPoseからは次のようにして頭の位置、向きなどが拾えるようです。etc.あとはマニュアルどおりやればビルボードが出ました。手っ取り早く解決したい(サンプルコードを持ってくる)手っ取り早くサンプルコードをコピペして済ませる方法もありました。顔として認識できる領域があれば、そこを切り取ってDirectXテクスチャを作る切り取った顔領域をビルボードとして画面中央より少し左よりの位置にレンダリング顔領域と思われる領域の空間の少し上部に3Dモデルをレンダリング文字列をテクスチャとして生成する(direct2d)顔が認識できないもしくはカメラがない(エミュレータ)の場合は前述の文字列を書き込んだテクスチャをビルボードをレンダリングです。camera」のビルボードは出るので、必要箇所を抜粋すれば良いかと。試しに該当する機能を持ってきてみると、期待通りビルボードが表示できました。詰まったポイントがあったので2点ほど。シェーダーがコンパイルできない何も表示されない以下、サンプルコード引用時のトラブルシューティングです。サンプルコード引用したシェーダーのコンパイルに失敗するGeometryShaderを新たに作ってVisualStudioでコンパイルすると、こんなエラーが出ます。specifierこれはVisualStudioプロジェクトに後から追加したhlslファイルはコンパイラの設定が不足していることによるものです。maxvertexcountはgeometryShaderでのみ使えるアトリビュートなので、コンパイラに「これはgeometryShaderですよ」と教えてあげる必要があります。新しいhlslファイルをソシューションに組み込んだ直後の設定はこうなっています。この図ではシェーダーの種類が指定されていません。何シェーダを作るつもりなんでしょうね。GeometryShaderならこういう形で指定します。pixelShaderやVertexShaderも同様。シェーダーレベルは環境に合わせて適切なものを選択します。サンプルコード引用したが何も表示されないVisualStudio2015の生成するHoloLens用Direct3Dのテンプレートと、上記サンプルコードでは、行列の型が違っています。テンプレートではDirectX::XMFLOAT4X4を行列の型として使っていますが、サンプルコードではWindows::Foundation::Numerics::float4x4です。全体で統一が取れていればいいので、どちらかに合わせてしまいましょう。内部構造が少し違うのかなと推測していますが、追うの面倒なので「やっぱ型は合わせたほうがいいよね」程度で。文字列をテクスチャとして生成できているか謎そもそも基本的な機能が動いていないとお話になりませんよね。テクスチャがすべて黒だった(=何も表示されていないように見えていただけ)なんて悲しい思いはしたくないものです。テクスチャが生成されていない/テクスチャの参照が失敗しているかもと不安な場合は、pixelshaderでテクスチャサンプラを使わずに単色出力を試すと幸せになれます。1は不透過で、白色単色のビルボードが出るので、最初はこうしておけば問題切り分けに役立ちます。感想と今後の展望とりあえずビルボードをレンダリングできるようになりました。HoloLensの座標系も少し詳しくなりました。コード整理して、いつでもデバッグ用に組み込める形にしてから次のステップに移りたいと思います。それでは今回はこれにて。23:17Hololensでビルボードを表示するTweet広告を非表示にする関連記事2018-05-13hololensの空間マッピングに触れる久しぶりのブログ記事です。Hololensの空間マ...2017-06-10古典的な手法を使ってMTGのカードを検出する古典的な方法で画像中からMTGのカードを取り出す実験をしてみま...2017-05-26DirectXのHLSLシェーダーをデバッグするDirectXのデバッグが捗る便利な機能があるのを知りました。HoloLensでARをやってみました。»プロフィールid:Catalina1344ソフトウェアやハードウェアの備忘録。後で逆引きできるように。OpenMVSで3D再構築するOpenMVGを試してみる(環境構築+α)父の日ですね月別アーカイブ忍者AdMaxはてなブログをはじめよう!Catalina1344さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。