知識0からのUnityShader勉強

知識0からのUnityShader勉強

UnityのShaderをメインとして、0から学んでいくブログです。

【UnityShader】オブジェクトの色を変更する #3

前回の成果

f:id:soramamenatan:20190512201354p:plain

最小限のシェーダーでドラゴンが赤くなった。

soramamenatan.hatenablog.com


続きに行く前に

前回、変数のことについて不明だったのでそこからやっていこうと思います。

float/half/fixedの使い分け

3つの変数は全て、小数点を扱う際に使用します。
では、どのように使い分けるか。

bit数 精度 使用用途
fixed 11bit -2~2、1/256 テクスチャをサンプリングしてその後加工しない
half 16bit -60,000~60,000、小数点以下は3桁まで fixed、float以外
float 32bit 一般的なfloat ワールド座標、UV座標

floatの乱用はやめようってことですね。

light11.hatenadiary.com


続きをやってみる

前回同様、おもちゃラボ様を参考に記事を書いていきます。
今回の記事はこちら

nn-hokuson.hatenablog.com

シェーダー側で変数を定義する

Shader "Custom/property"
{
    SubShader{
            Tags{ "RenderType" = "Opaque"}
            LOD 200

            CGPROGRAM
            #pragma surface surf Standard fullforwardshadows
            #pragma target 3.0

            struct Input{
                float2 uv_MainTex;
            };

            fixed4 _BaseColor;

            void surf(Input IN, inout SurfaceOutputStandard o){
                o.Albedo = _BaseColor.rgb;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

行なっていることは非常に単純で、

void surf (Input IN, inout SurfaceOutputStandard o) {
            o.Albedo = _BaseColor.rgb;
        }

この関数の中で、_BaseColor変数に代入してあるrgb値を入れているだけです。


ただ、このままだと変数に何も値が代入されていないので

f:id:soramamenatan:20190516155823p:plain

これは、_BaseColor変数の初期値が入っているため黒くなっています。


スクリプト側で色を変える

using System.Collections;
using UnityEngine;

public class ChangeColor : MonoBehaviour{
    void Start(){
        // shaderで定義した、_BaseColor変数の色を変更する
        GetComponent<Renderer>().material.SetColor("_BaseColor",Color.yellow);
    }
}

これだけで実装できます。
特に難しいこともしていないので、説明は省きます。

スクリプトで実装しているので、実行しないと色が変わりません。
実行してみます。

f:id:soramamenatan:20190516164259p:plain

ですが、これですと色を変更するのにいちいちスクリプトを変更しないといけないので手間です。


プロパティの作成

Shader "Custom/property"
{
    // ここを追加
    Properties{
        _BaseColor("Base Color",Color) = (1,1,1,1)
    }
    // ここまで
    
    SubShader{
            Tags{ "RenderType" = "Opaque"}
            LOD 200

            CGPROGRAM
            #pragma surface surf Standard fullforwardshadows
            #pragma target 3.0

            struct Input{
                float2 uv_MainTex;
            };

            fixed4 _BaseColor;

            void surf(Input IN, inout SurfaceOutputStandard o){
                o.Albedo = _BaseColor.rgb;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

Propertiesブロックを追加しました。

Properties

定義の仕方は以下の通りです

※ _BaseColor("Base Color",Color) = (1,1,1,1)の場合

変数名 inspectorの表示名 型名 デフォルト値
_BaseColor "Base Color" Color (1,1,1,1)

型はColor以外にも勿論あります。

|型名|用途| |Color|色を指定する| |Range(min,max)|スライダーで範囲指定(不動小数点)| |2D|テクスチャを指定する| |Float|不動小数点| |Vector|ベクトル|

詳しくは下記サイト様に記載してあります。

docs.unity3d.com

unitygeek.hatenablog.com

inspectorから値を変更する

f:id:soramamenatan:20190602151549p:plain

おお〜〜〜!できた! これでわざわざソースコードを変更しなくても色の変更ができますね!

ソースコードにコメントを付与

Shader "Custom/property"
{
    // inspectorに表示する
    Properties{
        // 色を変更する
        _BaseColor("Base Color",Color) = (1,1,1,1)
    }

    SubShader{
            // 後で理解する
            Tags{ "RenderType" = "Opaque"}
            LOD 200

            // 後で理解する
            CGPROGRAM
            #pragma surface surf Standard fullforwardshadows
            #pragma target 3.0

            // input構造体
            struct Input{
                // 必要ないが、surf関数を使うために仕方なく使用
                float2 uv_MainTex;
            };

            // 色を変更する変数
            fixed4 _BaseColor;

            // surf関数
            void surf(Input IN, inout SurfaceOutputStandard o){
                // ベースカラーをプロパティから変更した色に変える
                o.Albedo = _BaseColor.rgb;
            }
        // 後で理解する
        ENDCG
    }
    // 後で理解する
    FallBack "Diffuse"
}

次から本格的にshaderを触ることになりそうです!

継続して、勉強していきます!