こんにちは、
GMOインサイト エンジニアのfujimaruです。
UnityにはシェーダーでLOD(Level of Detail)を実現する仕組みがありますが、
参考になりそうな資料が無いので、簡単なコードを使って検証を行いました。
今回は、Unity5.4.0f3を使用し、
シェーダーLODの仕組みを使ってスクリプトからサブシェーダーを切り替える をゴールとします。
UnityのシェーダーLODについては、以下URLを参考にしてください。
https://docs.unity3d.com/Manual/SL-ShaderLOD.html
早速ですが、シェーダーのコードは、以下を用います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Shader "Custom/NewSurfaceShader2" { SubShader { LOD 150 Pass{ // 赤 Color(1,0,0,1) } } SubShader { LOD 100 Pass{ // 緑 Color(0,1,0,1) } } SubShader { LOD 50 Pass{ // 青 Color(0,0,1,1) } } SubShader { Pass{ // 白 Color(1,1,1,1) } } } |
サブシェーダーを4つ用意し、閾値(LOD)を設定しています。
サブシェーダーに設定されたLODと比較する値をスクリプトから送り、サブシェーダーを切り替えてみようという事です。
今回、サブシェーダーにロジックは無く、単に色を返すのみ となります。
次に、スクリプトのコードは、以下を用います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Cube : MonoBehaviour { public Renderer rend; // Use this for initialization void Start () { rend = GetComponent<Renderer> (); // 今回の肝 rend.material.shader.maximumLOD = 5; } // Update is called once per frame void Update () { } } |
Unityエディター上で作成したCubeに紐つくスクリプトコードです。
9行目が、LODと比較する数値の指定となります。
比較方法ですが、
LOD(シェーダー) <= rend.material.shader.maximumLOD(スクリプト) の時、サブシェーダが有効になります。
比較は、ソースコードの上から順に行われるので、
LODの値は、ソースコードの下になるにつれて、小さくなるように実装する必要があります。
スクリプトの値を変更した時の、実行結果は、以下のようになります。
1.rend.material.shader.maximumLOD = 5
2.rend.material.shader.maximumLOD = 50
3.rend.material.shader.maximumLOD = 100
4.rend.material.shader.maximumLOD = 150
うまくサブシェーダーが切り替わっているようです。
スクリプトの値の更新を、Update内で実行しても、同じ結果が得られました。
今回わかったこと
・シェーダーLODの仕組みを使えば、動的にサブシェーダーを切り替えることができる。
感想
対象プラットフォームが複数ある場合、
PCやAndroid等ユーザーによって環境が大きく異なる場合に有効かと考えております。