Unity シェーダーチュートリアル シェーダーLOD
シェーダー
以前に書いた、「基本とサーフェースシェーダー」の記事で軽く説明した、
シェーダーLOD (Level Of Detail) について、もう少し詳しく書いていきます。
SubShader{} について
シェーダーLOD の説明に入る前に、SubShader{} の役割の1つを説明します。
Unityのシェーダーが、基本的には以下の構造になっている事を、以前に説明しました。
Shader xxx/yyy {
Propaties {
・・・・・・・・・・
}
SubShader {
・・・・・・・・・・
}
Fallback "・・・・・・・・・・"
}
Propaties{} でアーティストに設定させるプロパティを作って、
SubShader{} で実際の処理を書いて、
Fallback で滑り止めを設定する。
という流れですね。
そして、SubShader{} は複数記述する事ができます。
Shader xxx/yyy {
Propaties {
・・・・・・・・・・
}
SubShader { // シェーダー1
・・・・・・・・・・
}
SubShader { // シェーダー2
・・・・・・・・・・
}
SubShader { // シェーダー3
・・・・・・・・・・
}
Fallback "・・・・・・・・・・"
}
複数の SubShader{} を記述する事で、
Fallback よりも順位の高い滑り止め効果を持たせる事ができます。
記述している順番に SubShader{} を調べて、描画できるものを選択します。
どの SubShader{} も描画できない場合の最終手段で、Fallback を使用します。
そして、それぞれの SubShader{} に LOD値 を持たせる事ができます。
LOD 数値
シェーダーLOD の役割
SubShader{} が複数記述されている場合、
通常は、上から順番かつハードウェアが描画できるものを選択して使用されます。
しかし、シェーダーLOD の機能を使用すれば、
下のレベルのシェーダー(本来滑り止めとして発動されるべき、下の SubShader{} )を
強制的に描画させる事ができます。
使用目的としては、例えば、以下のような場合などです。
モバイル端末のゲームアプリを制作しているとします。
対応端末は、古いものから新しい物まで様々です。
リッチな見た目を目指して、新しい端末のレベルに合わせてシェーダーを作っています。
古い端末は、Fallback で低レベルのシェーダーを設定して対応します。
しかし、中レベルの端末で問題が発生しました。
ハードウェア的にはリッチなシェーダーに対応しているのですが、
能力が追いついておらず、動作が重すぎます。
なまじハードウェアが対応しているせいで、 Fallback も発動しません。
そんな時に、シェーダーLOD の出番です。
例えば、低いFPS値を検出した時に、強制的にシェーダーのレベルを下げれば、
パフォーマンスを確保する事ができます。
シェーダーLOD の使い方
例として、以下のように LOD値 を設定したとします。
Shader xxx/yyy {
Propaties {
・・・・・・・・・・
}
SubShader { // シェーダー1
LOD 500
・・・・・・・・・・
}
SubShader { // シェーダー2
LOD 400
・・・・・・・・・・
}
SubShader { // シェーダー3
LOD 300
・・・・・・・・・・
}
Fallback "・・・・・・・・・・"
}
そして、このシェーダーに対して、スクリプトで以下のメソッドを実行すると・・・
Shader.maximumLOD = 400;
「お前のレベルは400だ。だから LOD 500 の描画はできない事になっている。」
「LOD 400 の SubShader{} を描画しろ。」
となり、シェーダー2が使用されます。
ハードウェア的にはシェーダー1を描画できたとしても、動作がとても重いので、
強制的にシェーダー2を使用させる事で、パフォーマンスを確保するのです。
また、以下のメソッドで個別ではなく、すべてのシェーダーに LOD値を設定する事もできます。
Shader.globalMaximumLOD
おわりに
通常は LOD(Level Of Detail) の名の通り、パフォーマンス確保を目的として使用しますが、
演出として、パッと別の表現に変えたい時にも使用できるかもしれません。