visionOSで描画順を制御する
概要
半透明を描画する際に描画順が想定と違い、意図した描画にならないケースがあります。
その際には 描画順を制御することが可能なのでその方法を解説します。
半透明の描画順問題
半透明の描画を行う際にははじめに奥に描画されるものを描画してから手前に描画するものを描画して、後ろの描画結果に重ねることで表現しています。
この時にカメラから遠いところから描画をするため、カメラの見る角度によって前後関係が変わってしまい、内側に存在するものが描画されずに見えなくなってしまいます。
これを回避するために描画順を明示的に指定して、指定した順番で描画することで回避していきます。
描画順の指定方法
描画順を指定するにはModelSortGroup
とModelSortGroupComponent
使用します。
まずは 対象のEntityをシーンから取得します。
var sphereSmall = scene.findEntity(named: "SphereSmall")
var sphereMedium = scene.findEntity(named: "SphereMedium")
var sphereLarge = scene.findEntity(named: "SphereLarge")
ModelSortGroup
を作成して描画順を管理するグループを作成します。
let modelSortGroup = ModelSortGroup()
次にグループ内での描画順を設定します。
各EntityごとにModelSortGroupComponent
をつけて描画順を設定します。
設定がしやすいようにまずは関数化しておきましょう。
func setEntityDrawOrder(_ entity:Entity, _ sortOrder:Int32, _ sortGroup:ModelSortGroup) {
let component = ModelSortGroupComponent(group: sortGroup, order: sortOrder)
entity.components.set(component)
}
この関数を使用して描画順を設定していきます。
中にある小さいEntityから描画されるようにしていきましょう。
setEntityDrawOrder(sphereSmall!, 1, modelSortGroup)
setEntityDrawOrder(sphereMedium!, 2, modelSortGroup)
setEntityDrawOrder(sphereLarge!, 3, modelSortGroup)
これで描画順を指定することができました。
実行してみると、描画順がどの角度から見ても正しくなっているのが確認できます。
DepthPassの設定
ModelSortGroup
にはdepthPass
を指定して前後関係の深度情報とカラーの情報を分けて描画することもできます。
prePass
を指定すると深度情報を先に描画してからカラーを描画し、postPass
を指定すると深度情報を後に描画することができます。
let modelSortGroup = ModelSortGroup(depthPass: .prePass)
let modelSortGroup = ModelSortGroup(depthPass: .postPass)
同じ描画順でprePass
を指定し深度情報を先に書き込むと、中に描画されているオブジェクトは前後関係が後ろになり、手前の大きい球に隠れる判定となり描画がされなくなります。
まとめ
半透明の描画は描画順番が重要となるため、必要に応じて描画順番を指定して、想定通りの描画順になるように気をつける必要があります。
また、ModelSortGroup
はモデルの描画順を制御するものなので、パーティクルの描画順の制御には使用できません。
半透明と半透明のパーティクルを同時に描画するのは避けた方が良いです。
参考
書いた人
佐藤 寿樹
株式会社コナミデジタルエンタテインメントに入社し5年間ウイニングイレブンのオンライン実装に携わる。
その後、株式会社コロプラで9年間エンジニアとしてアプリ開発・運用を行い、位置情報やARを使用したARゲーム開発、OculusRiftやPSVRなどのVRゲーム開発を経験しMESONへ入社。
MESON Works
MESONの制作実績一覧もあります。ご興味ある方はぜひ見てみてください。
Discussion