Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

シェーダで色を変更する、おまじないを省いたコード付き

f:id:weed_7777:20171031222836p:plain

緑と青をうっすらと塗ります。

おまじないを省いたコード

Shader "Custom/MyVertexShader4" {
    color += float4(0.0, 0.5, 0.5, 1.0);
}

コード全体

Shader "Custom/MyVertexShader4" {
    Properties {
        _Texture("Texture", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert finalcolor:mycolor
        struct Input {
            float2 uv_Texture;
        };
        sampler2D _Texture;

        void mycolor(Input IN, SurfaceOutput o, inout fixed4 color) {
            color += float4(0.0, 0.5, 0.5, 1.0);
        }
        void surf(Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D(_Texture, IN.uv_Texture).rgb;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

頂点シェーダに挑戦、おまじないを省いたコード付き

f:id:weed_7777:20171031215324p:plain

各頂点のx座標を3、y座標を3増やすような頂点シェーダを書いてみます。

おまじないを省いたコード

Shader "Custom/MyVertexShader3" {
    v.vertex.x += 3;
    v.vertex.z += 3;
}

おまじないを含んだコード

Shader "Custom/MyVertexShader3" {
    Properties {
        _DiffuseColor("Diffuse Color", Color) = (1.0, 1.0, 1.0)
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert vertex:vert
        struct Input {
            float4 color: COLOR;
        };
        float3 _DiffuseColor;

        void vert(inout appdata_full v) {
            v.vertex.x += 3;
            v.vertex.z += 3;
        }
        void surf(Input IN, inout SurfaceOutput o) {
            o.Albedo = _DiffuseColor;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

シェーダからおまじないを取り除いた裸のコードはシンプルだった

Unityのシェーダの勉強を始めました。

まず、シェーダを書くにはSublime TextShaderLangageというパッケージを入れるとSyntaxHighlightされて書きやすいです。

f:id:weed_7777:20171031142055p:plain

さて、最初に勉強するシェーダのコードはほとんどがおまじないだとわかりました。

例えば以下のコード。

Shader "Custom/MyShader" {
    SubShader{  // おまじない
        Tags{  // おまじない
            "RenderType" = "Opaque"  // おまじない
        }
        CGPROGRAM  // おまじない
        #pragma surface surf Lambert  // おまじない
        struct Input {  // おまじない
            float4 color : COLOR;  // おまじない
        };
        void surf(Input IN, inout SurfaceOutput o) {  // おまじない
            o.Albedo = half3(1.0, 0.5, 0.4);
        }
        ENDCG  // おまじない
    }
}

つまり、以下のようになります。

Shader "Custom/MyShader" {
    o.Albedo = half3(1.0, 0.5, 0.4);
}

halfというのはデータの型で、以下のページに一覧が載っています。

docs.unity3d.com


以下引用です:

高精度: float

float は最高精度の浮動小数点値で、通常のプログラミング言語の float と同じように一般な 32 ビットです。

ワールド空間位置、テクスチャ座標、複雑な関数を含むスカラー計算 (三角法、累乗法など) には、 たいてい 32 ビットの float が使用されます。

中精度: half

half は中精度の浮動小数点値で、一般に 16 ビットです (–60000 から +60000 の範囲で、小数点以下約 3 桁)。

Half は、ショートベクトル、方向、オブジェクト空間位置、HDR カラー に使用されます。

低精度: fixed

fixed は低精度で、固定小数点数です。一般的に 11 ビットで、–2.0 から +2.0 の範囲で、1/256 精度です。

固定精度は、標準カラー (一般的に標準テクスチャに保管されるので) とそれらの単純な制御に使用されます。

f:id:weed_7777:20171031171422p:plain

おお、これなら俺でもわかる。とにかくも一歩前進。

UnityのUpdate()をマネージャで管理して、重くて遅かったアプリを軽く速くする

処置前:

f:id:weed_7777:20170920134522p:plain

処置後:

f:id:weed_7777:20170920134552p:plain

「先輩、Unityアプリが重いんですけど」

「1フレームでUpdate()は何回呼んでる?」

「100回です」

「あー、それはマネージャをつくって管理した方がいいな。やり方を教えよう」

「ありがとうございます!」

UnityのUpdate()のコールは数が多いとアプリの実行の負担になります。そこで、Update()をUpdateManagerで管理してみましょう。プロファイラーを見ると違いがハッキリわかります。

こんな感じで書きます:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UpdateManager : MonoBehaviour
{
    public List<ManagedUpdateBehavior> list = new List<ManagedUpdateBehavior>();

    // Update is called once per frame
    void Update()
    {
        var count = list.Count;
        for (var i = 1; i < count; i++)
        {
            list[i].UpdateMe();
        }
    }
}

アプリ起動時にインスタンスをマネージャのlistプロパティに追加します:

void Start()    
    {
        
        ...

        // Update Managerに自分を登録する
        UpdateManager um = GameObject.Find("UpdateManager").GetComponent<UpdateManager>();
        um.list.Add(this);
    }

するとプロファイラの様子が、こんな感じから…

f:id:weed_7777:20170920134522p:plain

こんな感じに変わります:

f:id:weed_7777:20170920134552p:plain

60FPSが見えてきました!


より詳細はUnity公式の以下の記事が参考になります:

blogs.unity3d.com