9
5

More than 3 years have passed since last update.

[Unity]Shader書く人は.cgincがあると幸せになれる

Posted at

前書き

一度ShaderGraphを使用してあまりの便利さにLabで書くのをやめようとしたDemです。
Unityも便利な機能が増えてきていますが、やはり勉強しながらならちゃんと書いた方がいいですね。

よく使われるやつ

よくUnlitShaderを書く際に#include"UnityCG.cginc"と書くことがありますね。
これを読み込むとUnity側が用意してくれている便利な機能が一通り使用可能になります。そもそも作成時でデフォルトで書かれていますが。
実際このUnityCG.cgincの中身もGitHubから見ることができたりします。
こちらから飛ぶことができます。
使用していてもまだまだ使ったことない機能がたくさんありますね・・・。

.cginc作ってみよう

自作した関数などを.cgincにまとめていつでも使えるようにしてみましょう。
作り方は簡単で...
メモ帳を作って拡張子を.cgincにするだけです。
コメント 2020-07-14 141635.png
はい、これだけです。簡単ですね。あとはこの中に自作関数を記述するだけです。
では、サンプルとして僕がテストで割と使用するリムライトを.cginc内に記述してみましょう。

Hoge.cginc
//RimLightの計算
//1:
float UnlitRimLight(float3 normal, float3 worldPos, float rimPower) {
    //頂点のワールド座標からカメラの位置のベクトルを求める
    float3 L = normalize(worldPos.xyz - _WorldSpaceCameraPos.xyz);
    //dotで値が0だと垂直で、1だと平行 1-して値を逆にする
    float d = 1 - saturate(abs(dot(normal, L)));
    d = pow(d, rimPower);
    return d;
}

読み込み方法は同じで#include".cgincファイル"で読み込みます。

RimLight.shader

Shader "Unlit/RimLight"
{
    Properties
    {
        _RimPower("Rim Power",Range(0.1,5.0)) = 2
        [HDR]
        _RimColor("Rim Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "../cginc/Hoge.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float3 normal:NORMAL;
                float3 worldPos:TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float _RimPower;
            float4 _RimColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.normal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normal = normalize(i.normal);
                float c = UnlitRimLight(normal,i.worldPos,_RimPower);
                return _RimColor * c;
            }
            ENDCG
        }
    }
}


fragの部分がずいぶんとすっきりしますね。関数名もしっかりと命名すればどんな機能かもわかりやすくなります。
読み込み方が"../cginc/Hoge.cginc"となっているのはファイルパスの問題です。Shaderから見て.cgincファイルがどこにあるのかを
把握して読み込みましょう。
僕はこんな感じでcgincとShaderのファイルを分けているため、上記のような書き方をしています。
コメント 2020-07-14 141359.png

終わりに

Shaderを書いて汎用性があるならとりあえずcgincにまとめてみるのもいいでしょう。肥大化してきたら機能ごとに分けたりすると後々使いやすくなったりもしますからね。

ではでは、またどこかで・・・。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5