夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

UnityでビルドインシェーダーマクロのUnityCG.cgincの中身を見る方法

本日はShader枠です。

〇UnityCG.cgincとは?

UnityCG.cgincはUnityで提供されている組み込みのシェーダーファイルで、ヘルパーメソッドと定義を提供しています。

例えばUnityObjectToClipPos()などのUnity座標や空間に合わせてデータを与えるだけで変換してくれるメソッドなどがあり、これによってUntiyの機能を使用したShaderを開発できます。

通常#include "UnityCG.cginc"のように定義し使用します。

Shader "Unlit/NewUnlitShader 1"
{
    Properties
    {
       ・・・
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

 しかしこの定義ファイルはUnityプロジェクトに含まれないため、通常はファイルの内部を見ることはできません。

今回はこの定義などを開いてみていきます。

通常は勉強などの用途以外では行うことは少ないと思いますが、今回はMixedRealityGraphicsToolsのバグが内部定義由来の可能性が高いと判断したため読んでいきます。

redhologerbera.hatenablog.com

〇UnityCG.cgincのファイルのパス

UnityCG.cgincはUnityエンジンの保存パスにあります。

UnityHubを経由してUnityを導入した場合は次のようなパスになります。

"C:\Program Files\Unity\Hub\Editor\2021.3.5f1\Editor\Data\CGIncludes\UnityCG.cginc"

上記例ではUnity2021.3.5f1での例ですが、バージョンごとにファイルは存在します。

通常のプログラムファイル同様にIDEで開くことで確認できます。

同様に"C:\Program Files\Unity\Hub\Editor\2021.3.5f1\Editor\Data\CGIncludes\のパスには他のShaderヘルパー関数もあります。

ここで今回のバグの原因となるUnpackScaleNormal関数の定義があるUnityStandardUtils.cgincを見ていきます。

これでようやくUnpackScaleNormalの定義を見つけることができました。

half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
{
    return UnpackScaleNormalRGorAG(packednormal, bumpScale);
}

half3 UnpackScaleNormalRGorAG(half4 packednormal, half bumpScale)
{
    #if defined(UNITY_NO_DXT5nm)
        half3 normal = packednormal.xyz * 2 - 1;
        #if (SHADER_TARGET >= 30)
            // SM2.0: instruction count limitation
            // SM2.0: normal scaler is not supported
            normal.xy *= bumpScale;
        #endif
        return normal;
    #elif defined(UNITY_ASTC_NORMALMAP_ENCODING)
        half3 normal;
        normal.xy = (packednormal.wy * 2 - 1);
        normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
        normal.xy *= bumpScale;
        return normal;
    #else
        // This do the trick
        packednormal.x *= packednormal.w;

        half3 normal;
        normal.xy = (packednormal.xy * 2 - 1);
        #if (SHADER_TARGET >= 30)
            // SM2.0: instruction count limitation
            // SM2.0: normal scaler is not supported
            normal.xy *= bumpScale;
        #endif
        normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
        return normal;
    #endif
}

Unityで定義されている組み込みファイルはこちらのパスを参考にすればよさそうです。

本日は以上です。