SceneKitのSCNTechniqueを使って物体の輪郭を光らせる


SceneKitでできるシェーダー表現の1つ、SCNTechniqueを使って物体の周りを光らせる方法を紹介します。

ただし、僕も完全に理解していないので、実装の流れを説明することにフォーカスし、細かい説明はまたの機会にします。

完成イメージ

作り方概要

  • metalファイル作成
  • plistファイルでDictionaryを作成
  • SCNTechniqueを作ってSceneViewに渡す
  • 適応するNodeのcategoryBitMaskを設定

このような流れです。

metalファイル作成

shaderを実行するmetalファイルを作ります。僕はこれを完全に理解していません。これから頑張って理解します。

https://github.com/laanlabs/SCNTechniqueGlow のコードを参考に、真似して作ってみました。僕のサンプルコードはここにあります。

plistファイルでDictionaryを作成

最終的にSCNTecniqueにはDictionary型を渡すので、plistを作ってDictionaryを定義します。keyとvalueはApple公式の https://developer.apple.com/documentation/scenekit/scntechnique に書いてますが、覚えるのはきついですねw

僕もこれからサンプルをいじって試しながら覚えていきたいと思います。

SCNTechniqueを作ってSceneViewに渡す

NodeTechnique.plistからdictionaryを取り出し、SCNTechniqueをinitします。つまり、必ずしもplistである必要はなく、元ファイルはJSONなどでも良いです。もちろんコードで作ることもできます。(長いけど)

if let path = Bundle.main.path(forResource: "NodeTechnique", ofType: "plist"),
    let dict = NSDictionary(contentsOfFile: path) as? [String : Any] {

    let technique = SCNTechnique(dictionary: dict)
    sceneView.technique = technique
}

適応するNodeのcategoryBitMaskを設定

先のplistで、includeCategoryMaskを2としているので、categoryBitMaskが2のnodeにだけ、該当のshaderが適用されます。

categoryBitMaskのデフォルトは1です。

let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)
box.firstMaterial?.diffuse.contents = UIColor.darkGray
let node = SCNNode(geometry: box)
node.categoryBitMask = 2

完成品

光る赤い枠線がBoxNodeに適用されました。ダークサイド感ありますね。

参考