夜風のMixedReality

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

Unity URP、ビルドインそれぞれで処理を変えるShaderを描く

本日はShader学習枠です。

6月より取り組んでいるMixedRealityGraphicsTools(MRGT)のメインとなるGraphicsToolsStandardShader(MRGTStandardShader)ではUnityのレンダーパイプラインであるURPだけでなくビルドイン両方で、ユーザーはパラメータを一切変えることなくShaderを使うことができました。

今回はこの仕組みを使い独自のシェーダーを実装していきます。

○URPとビルドインで処理を分けるシェーダー

今回は次のコードを描きました

Shader "Unlit/URPBuildInTest"
{
      SubShader
    {
        PackageRequirements
        {
            "com.unity.render-pipelines.universal": "10.6.0"
        }

        Tags
        { 
            "RenderPipeline" = "UniversalPipeline"
            "RenderType" = "Opaque" 
        }

        // Default pass (only pass outside of the editor).
        Pass
        {
              HLSLPROGRAM
               #pragma vertex vert
        #pragma  fragment frag
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        //Lighting.hlslがライト情報を格納するコアpackage
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"

  struct appdata_t
        {
            float4 vertex:POSITION;
            float2 uv : TEXCOORD0;
            half3 normal: NORMAL;
        };

        struct v2f
        {
            float4 vertex : SV_POSITION;
            float2 uv : TEXCOORD0;
            float3 normalWS : TEXCOORD1;
        };

        v2f vert (appdata_t v)
        {
            v2f o;
            o.vertex = TransformObjectToHClip(v.vertex);
            //面の法線を取得、ライトの当たる向きを計算
            VertexNormalInputs normal = GetVertexNormalInputs(v.normal);
            o.normalWS = normal.normalWS;
            return  o;
        }
        float4 frag(v2f i):SV_TARGET
        {
          //Light.hlslで提供されるUnityのライトを取得する関数
          Light lt = GetMainLight();
          float4 col = (1,1,1,1);
          //ライトの向きを計算
          float strength = dot(lt.direction, i.normalWS);
             float4 lightColor = float4(lt.color, 1);
          return col* lightColor*strength;
        }
              ENDHLSL
        }
        }
    
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
                  #include "UnityCG.cginc"
                  struct appdata
                  {
                    float4 vertex : POSITION; 
                  };
                  
                  struct v2f
                  {
                    float4 vertex:SV_POSITION;
                  };
                  
                  v2f vert(appdata v)
                  {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    
                    return o; 
                  }
                  
                  float4 frag(v2f i):SV_Target{               
                    float4 col =float4(0,1,0,1);
                    return col;
                  }
            ENDCG
        }
    }
}

○PackageRequirements

PackageRequirementsブロックはShaderLab内でそのシェーダーが実行対象となるために必要となる機能を記述します。

docs.unity3d.com

今回の場合パッケージバージョン指定でURPのパッケージを指定しています。

    PackageRequirements
        {
            "com.unity.render-pipelines.universal": "10.6.0"
        }

 これによって一つ目のSubShaderはURP専用となり、ビルドインでは動かなくなります。

 ビルドインでは次に記述されているSubShaderのほうが読み込まれるためビルドインも正常に描画されます。

 今回は一つ目のURP用のSubShaderの処理でライトの処理、2つ目のビルドイン用の処理でUnlitの緑色になるように処理を記述しているためUnityエディタ上でも想定通りに動いていることを確認できました。

ビルドインでシェーダーを実行した様子 

URPで同じシェーダーを実行した様子

本日は以上です。