SceneKitの物理ベースレンダリング(PBR) / magicien 

SceneKitで物理ベースレンダリングを使うには、SCNMaterial.lightingModel = .physicallyBased と設定すれば良い。
つまり、材質によって物理ベースにしたりしなかったりできる。ややこしいね!

physicallyBased の説明によると、
  • 描画に使う SCNMaterial の主なパラメータは、diffuse、roughness、metalness の3つ。
  • 細かい表現には、normal、ambientOcclusion、selfIllumination を使う。
  • ambient、specular、reflective、shininess、fresnelExponent、locksAmbientWithDiffuse は無視される。
  • 他に SCNScene.lightingEnvironment、SCNCamera.wantsHDR を設定すると良い感じになる。
ということらしい。言及すらされない emission さんかわいそう。
ただし、renderingAPI が Metal でないとPBRが有効にならない。GLSLでも実装上問題無いと思うんだけど、シェーダを二種類書くのが面倒だったのかな。

物理ベースでない場合、水面に映り込む背景等は、reflectiveに設定していたけれど、物理ベースの場合は、SCNScene.lightingEnvironment を使うようだ。材質毎に背景を変える理由もないし、こっちの方が良い気がする。
個別に設定したい場合は、selfIllumination を使うと、diffuseの計算に使うテクスチャを変えることができるらしい。
PBRでemissionを使いたい場合、emissionを設定した上で、selfIllumination.content を nil に設定すれば良いようだ。

JSceneKitでシェーダを書くと、上記情報だけでは、フレネル項のパラメータが一つ足りないことに気づく。物理ベースじゃなくてもフレネル反射はしていたので、これまで適当に固定値を割り当てて計算していたけれど、SceneKitではどう計算しているのだろう。
試しにFox2をPBRで描画してみたら、地面が暗すぎてよく見えなくなった。というわけでHDR(トーンマッピング)にも対応せねばなるまい。

2017/08/16(Wed) 04:10:41