iOS で SceneKit を試す(Swift 3) その47 - Scene Editor の Omni Light と Attenuation
豆電球のような Omni Light の設定を見ていく。
Omni Light は設置位置によって光の影響を変化させるが、ジオメトリの影を落とすことはできない。
影は必要ないが光の影響を与えたい場合などで使用するのが良いかと思われる。
シーン設定
ひとまず、iOS SceneKit のテンプレートでプロジェクト作成。
ship.scn を開き Object Library (Command + Option + Control + 3) から Floor をシーンにドラッグ。
Node Inspector (Command + Option + 3) を開いて y を -2 に設定。
Scene Graph View から shipMesh を選択し、マテリアルを Physically Based に変更。
光の影響を受けないためジオメトリが黒くなる。
Omni Light の設定
Object Library から Omni Light をシーンにドラッグ。
Omni Light は距離影響を受けるので Node Inspector (Command + Option + 3) を開いて y の 10 に設定。
宇宙船にライトが当たると思われる、
今回は Scene Editor 上で動作を見ていくが、実機で動かす場合は GameViewController.swift にあるライトの記述をすべて消す。
Omni Light の Attrubutes Inspector
Attrubutes Inspector (Command + Option + 4) を開くと、
以下のようなパラメーターが現れ、
以前紹介した共通の設定以外では Attenuation がある。
試しに Intensity を 500 にしてみたもの。
Attenuation
直訳すると減衰となり、光がどう減退するかを設定する。
Start
減衰の開始の距離。
デフォルト値は 0.0 でライトの設置場所から行われる。
End
減衰の終了距離。これ以降は光の影響を受けない。
デフォルト値が 0.0 で適応範囲は無限遠となりかなりなだらかな減衰となる。
30 に設定するとこの形
Falloff
減衰の状態を表す。
デフォルト値が 2.0
値: 0 の場合は完全に減衰は行われない。
値: 1 で開始から終了までを線形で光が減衰する。
値: 2 デフォルト設定。2乗の曲線を描き光が減衰する。2以降はパラメーターの数の乗数で光が減衰する。
値: 4 値を大きくしいくと全体の変化が少なくなる。
また、減衰はシーンエディタで有効範囲が表示される。
コード
let light = SCNLight() light.name = "omni" light.type = .omni light.intensity = 1000 light.attenuationStartDistance = 0.0 light.attenuationEndDistance = 30.0 light.attenuationFalloffExponent = 2.0 let lightNode = SCNNode() lightNode.light = light lightNode.position = SCNVector3(x: 0, y: 10, z: 0) scene.rootNode.addChildNode(lightNode)
今回はここまで。
iOS で SceneKit を試す(Swift 3) その46 - SCNLight の共通設定
前回の書き忘れがあったのでライトの種類の前にこちらの紹介。
ライトには種類があったが、Light Probe 以外でいくつかの共通設定があるので、まずはこちらから。
Name
コードで使用するための識別用の名前。
Light Probe でも使用可能。
Type
ライトの種類を SCNLight.LightType を使用し設定する。
以下、SCNLight.LightType のプロパティ
プロパティ | 名前 |
---|---|
.ambient | アンビエントライト |
.omni | オムニライト |
.directional | ディレクショナルライト |
.spot | スポットライト |
.IES | IES ライト |
.probe | Light Probe |
ちなみに、type の後に IES ライトのファイルを読み込む関数 iesProfileURL を使用すると、何が設定されていても IES ライトに変更される。
Mode
デフォルト値は Dynamic。
Static はライトマップのベイク作成時に使用。
この設定は Scene Editor 内でのベイクのためだけにあるようなので、SCNLight クラスにこのプロパティはない。
( 確か Model I/O の機能だったはず )
Color
ライトの色。この色と共にジオメトリなどのマテリアル設定に反映させ物体に色をつける。
Intensity
光の強さ。
値を上げると光沢の範囲が増えや形がシャープになる。
デフォルト値は 1000。
コードで使用可能な項目
temperature
色温度の単位、ケルビンでライトの設定を行う。
6500 K で白色となっており、低くすると赤みがかり、高くすると青くなる。
デフォルト値は 6500 になっており、設定できる値は 0 〜 40000
iOS SceneKit のテンプレートに SCNFloor を追加して、オムニライトに temperature を設定したもの。
// create and add a light to the scene let lightNode = SCNNode() lightNode.light = SCNLight() lightNode.light!.type = .omni // 追加箇所 lightNode.light!.temperature = 3000 lightNode.position = SCNVector3(x: 0, y: 10, z: 10) scene.rootNode.addChildNode(lightNode)
以下で intensity と色をつけたもの
lightNode.light!.color = UIColor.init(red: 1.0, green: 0.8, blue: 0.8, alpha: 1.0)
categoryBitMask
ジオメトリのノードの categoryBitMask と ライトのビットマスクと AND 演算して 0 以外であった場合 このライトに適応させる。
デフォルトの値は -1 となっており、すべてのジオメトリに適応される。
注意:SCNLight をアタッチしている SCNNode ではなく、SCNLight の categoryBitMask を設定しないと変化しないので間違えないように。
注意2:アンビエントライトは categoryBitMask が無視されるため適応できない
init(mdlLight: MDLLight)
Model I/O で作成したライトを適応できる。
基本的には SceneKit で使用されているライトなので直接 MDLLight を設定することはないと思われる。
今回はここまで。
iOS で SceneKit を試す(Swift 3) その45 - Scene Editor の Light について
今回はシーンのライトについて軽くご紹介。
シーン上には必ずライトとなるものが1つ必要となり、
SCNNode で light プロパティに SCNLight を設定するか、
以前、紹介したシーン設定の Light Environment (Image Based Lighting) を設定することで、
ジオメトリのマテリアルに光を照らしカメラに物体を映すことができる。
SCNLight の種類
Directional と Ambient は設置場所に関係なく一定の光を設定する。
ライトの種類 | 説明 |
---|---|
Omni | オムニライト。豆電球のように球状に光が広がるライト |
Directional | ディレクショナルライト。太陽のように一定方向の光を設定するライト |
Spot | スポットライト。現実のスポットライト同様に円錐状に光を設定するライト |
Ambient | アンビエントライト。シーン全体に光を与えるライト |
IES | IES ライト。照明設定が記述されたテキストファイルを読み込み設定するライト |
Light Probe | これ自体はライトではなく、Light Probe 内に SCNMaterial の Emision が設定されたジオメトリがあった場合、そのジオメトリをライトに設定する |
SCNLight の制限
ドキュメントでは SCNLight はノードで使用できるの 8 つまでとのこと。
通常、ライトを 8 つ使用することはあまりないが、 軽く試したところ、アンビエントライトや 光の変更を行わないモードであるスタティックにしたライト、 ライトプローブを除くライトが 8 個以上あると 9個目からはライトが無視される。
SCNLight の注意点
3DCG はシーン内のライトの数と種類でレンダリングパフォーマンスが変化する。
SceneKit で効率的なレンダリングを行う場合、シーン内のライティング設定を見直す必要がある。
以下、調整例
- 光の当たり方が固定の場合は、あらかじめ 3DCG のオーサリングツールでライトをライトマップテクスチャにベイクし、SCNMaterial にそのテクスチャ適応して multiply で色等を調整する
- 必要のないライトやジオメトリで影の描画を行わない
- ゲームキャラクタなど正確な影の形が必要ない場合、影を輪郭がぼやけた丸などの画像にしてしまう
- スポット、オムニ、ディレクショナルライト で attenuationEndDistance プロパティを設定し有効範囲を制限する
- SCNLight の categoryBitmask 使用してライトを必要ないジオメトリにはライトを適応しない
今回はここまで。
次回、種類別に紹介していく。
iOS で SceneKit を試す(Swift 3) その44 - Scene Editor モーションブラー
実際のカメラでは速い動きを物体を撮る際、カメラ性能にもよりますが残像が出る場合があり、
それを SceneKit のカメラである SCNCamera でシミュレーション行う。
Scene Editor の パラメーター
プロパティは一つのみ。
Motion Blur - Intensity
最大値を 大きくした場合、効果は顕著になる。
デフォルト値は 0.0 で効果は出ない。
また、ドキュメントでは Wide-Gamut Color (Display P3) では使用できず、
Info.plist で SCNDisableWideGamut のキーを設定し Bool 値で YES (true) にしてオプトアウトする必要がある。
サンプル
わかりやすく、大きめの値 4 で設定。
コード
let camera = SCNCamera() camera.motionBlurIntensity = 4
今回はここまで。
iOS で SceneKit を試す(Swift 3) その42 - Scene Editor カメラのポストプロセス
カメラとなる SCNCamara では画面描画後に簡易的な画像処理を行うことができる。
使用できる処理は以下のもの。
- 画面の周りを暗くするケラレ処理
- ブラウン管のような色のにじみを出すカラーフリンジ
- 簡易的な色の調整を行うカラーグレーディング
さらに複雑な処理をしたい場合は SCNTechnique を使用し、自前でシェーダーを書いて合成する。
Scene Editor の パラメーター
元画像
Vignetting
ケラレ処理を行う。
Power が適応範囲で、Intensity が適応度合い。
デフォルト値は Power が 0 で、Intensity が 1。
Power が 0 の場合は処理が行われない。
Power: 1 / Intensity: 1
Color Fringe
フリンジの処理を行う
Strength の値を大きくするほどフリンジの色のシフトと広がりが顕著になり、Intensity が適応度合い。
デフォルト値は Strength が 0 で、Intensity が 1。
Strength が 0 の場合は処理が行われない。
Strength: 4 / Intensity: 1
Color Grading
Saturation
画面の彩度を設定する。 デフォルト値は 1.0 で 0 にするとグレイスケールになる。
Saturation: 0
Contrast
画面のコントラスト変更する。
デフォルト値は 0.0。
Contrast: 4
コード
let camera = SCNCamera() // Vignetting camera.vignettingPower = 0.0 camera.vignettingIntensity = 1.0 // Color Fringe camera.colorFringeStrength = 0.0 camera.colorFringeIntensity = 1.0 // Saturation camera.saturation = 1.0 camera.contrast = 0.0
また、コードのみだがカラーグレーディング用のテクスチャを作成し、適応させると細かな色の調整ができる模様。
Color Grading のドキュメント
colorGrading - SCNCamera | Apple Developer Documentation
上記の設定でテクスチャ画像を作成し、
レンダリング画像に対して 80% の適応度合いで試したもの。
let camera = SCNCamera() camera.colorGrading.contents = NSImage(named:"colorgrading.png") camera.colorGrading.intensity = 0.8
カラーグレーディングの画像についてはまたいつか説明しようと思う。
今回はここまで。
iOS で SceneKit を試す(Swift 3) その41 - Scene Editor カメラの Depth of Field(被写界深度)
カメラとなる SCNCamara で被写界深度のシミュレーションを行う。
実際のカメラと同様に距離でオブジェクトにピントを合わせて、 他がボケるさせる効果の設定を行う。
ちなみに、今回紹介するすべてのプロパティが macOS, tvOS, watchOS でも廃止予定で、
iOS 11 など最新の OS からはカメラのシミュレーションに近い、焦点距離 (focusDistance) と F値 (fStop) で行う。
Scene Editor の パラメーター
Blur Radius
ピントがあっていないもの(被写界深度の外のもの)に対してボケ具合の最大値を設定する。
0 以上にしないと被写界深度のシミュレーションが行われない。
デフォルト値は 0.0。
Distance
ピントを合わせたいものまでの距離。焦点距離。
デフォルト値は 10.0
Aperture
レンズの口径を表す。
値を大きくすると焦点距離から鮮明に映る範囲が狭くなりボケる割合が大きくなり、
値を小さくすると全体がシャープになっていく。
デフォルト値は 0.125。
Size
オブジェクトが鮮明に表示される距離の範囲の大きさ。
デフォルト値は 0.0。
サンプル
以下の値に設定し、手前、2番目、3番目にピントを合わせたもの。
プロパティ | 値 |
---|---|
Blur Radius | 6 |
Aperture | 0.125 |
Size | 1 |
Distance: 1.2
Distance: 3
Distance: 6
コード
let camera = SCNCamera() camera.focalBlurRadius = 0.0 camera.focalDistance = 10.0 camera.aperture = 0.125 camera.focalSize = 0.0
今回はここまで。
iOS で SceneKit を試す(Swift 3) その40 - Scene Editor カメラの HDR 設定 Part2
引き続き HDR の説明。
カメラとなる SCNCamara の HDR とは、
トーンマッピング処理を行い、シーン全体の輝度値を、ディスプレイに表示できる狭い範囲の輝度値に変換するすること。
具体的には露出調整、Bloom 効果を表現する。
また、HDR は Scene Editor のカメラのプロパティにある HDR のチェックをオンにするか、
コードで SCNCamara の wantsHDR を true にしないと、どの機能プロパティを設定しても動作しない。
Scene Editor の パラメーター
HDR
HDR
チェックをオンにすると HDR の機能を動作できるようにする。
Average Gray
HDR を使用する際、Photoshop のトーンカーブのように光の情報をどのように LDR に適応するかトーンマッピングカーブを作成する。
Average Gray はトーンマッピングカーブの中間点として使用する輝度レベルを設定し、暗いまたは明るいコンテンツのシーンを調整することができる。
値を高くすると画面全体の輝度高くなり、 値を低くすると輝度低くなる。
デフォルト値は 0.18。
0.05
0.5
White Point
ハイライトとシャドウ間で光の情報の緩やかな遷移、または急な遷移を行う。
デフォルト値は 1.0
10.0
0.3
Adaptation
Auto Adapt
チェックを入れると、現在のカメラが映す輝度を自動的に測定し、それに応じて露出レベルを調整する。 さらに、遮蔽物などでシーンの輝度が変化すると、自動的に新しい露出レベルへ変更するアニメーションが行われる。
ドキュメントではデフォルトでオンとなっているが、値は false が返す。
Apple のコードサンプル Badger で洞窟から出る際、この効果が顕著に現れる。
Auto Adapt なし / あり
Speed Factor
Brightening と Darkening の値があり、暗い領域から明るくなる領域、または明るいところから暗くなる際の持続時間。
デフォルト値では Brightening は 0.4、 Darkening 0.5 と変化が異なる。
Exposure
Minimum、Maximum
露光量と最小値を最大値。
最小値を下げると暗い部分が露出不足(均一に黒)になり、
最大値をあげると露出オーバー(均一に白)になる。
1.0 で 2 倍、 2.0 で 4 倍、-1.0 で 1/2。
差が大きいほど、コントラストが低くなる。
デフォルトでは Minimum が -15、Maximum が 15。
Minimum -15、Maximum -3。
Minimum 1、Maximum -15。
Offset
トーンマッピングカーブの明暗にオフセット(偏り)をつける。
プラス値を与えると画面全体の輝度が上がり、マイナス値を与えると下がる。
デフォルト値は 0.0
-3
3
Bloom
ブルームエフェクトを与える。
ブルームエフェクトとは、シーンのハイライト(明るい色の領域)にソフトグローを追加し、明るいハイライトを実際の人間の目や物理カメラに表示する方法をシミュレートする。
輝度によって処理が行われるため、設定によってはエフェクトが表示されないことがあるので注意。
Intensity
ブルームエフェクトの強さを設定する。
値を小さくすると微妙な効果を得られ、大きくすると非常に明るい輝きが発生する。
デフォルト値は 0.0 で効果は現れない。
Threshold
ブルームエフェクトをトリガするために必要な輝度レベルを設定する。 値を小さくするとシーンの広範囲に適応され、 値を大きくするとハイライトのみにエフェクトが適用される。
デフォルト値は 1.0。
Blur Radius
ブルームエフェクトでハイライトに適用されるソフトグローのぼかしのピクセル単位の半径。
値を大きくすると広範囲で柔らかいグローが表現され、0 で無効になる。
デフォルト値は 4.0 ピクセル。
以下の設定を設定したブルームエフェクト
プロパティ | 値 |
---|---|
Exposure Offset | 2 |
Bloom Threshold | 6 |
Bloom Blur Radius | 18 |
コード
let camera = SCNCamera() // HDR camera.wantsHDR = true camera.averageGray = 0.18 camera.whitePoint = 1.0 // Adaptation camera.wantsExposureAdaptation = true camera.exposureAdaptationBrighteningSpeedFactor = 0.4 camera.exposureAdaptationDarkeningSpeedFactor = 0.6 // Exposure camera.minimumExposure = -15.0 camera.maximumExposure = 15.0 camera.exposureOffset = 0.0 // Bloom camera.bloomIntensity = 0.0 camera.bloomThreshold = 0.5 camera.bloomBlurRadius = 4.0
今回はここまで。