【Unity】【URP】Texture3Dをシェーダでサンプリングする

UnityのURPで、Texture3Dをサンプリングするシェーダを作る方法についてまとめました。

Unity2021.1.11f1
Universal RP 11.0.0 (シェーダはURP用のものとなります)

はじめに

Texture3Dは同じサイズとフォーマットのテクスチャを一つにまとめたアセットです。
シェーダでは三次元情報として保存され、三次元の座標を用いてサンプリングします。

docs.unity3d.com

この記事ではこのTexture3Dをサンプリングするシェーダを作成します。
なお本記事のシェーダはURP用のものとなります。

Texture3Dを作る

まずTexture3Dを作ります。
Unity2020.2からはインポート設定から作れるようになりました。
この辺りは以下の記事にまとめていますので、必要に応じて参照してください。

light11.hatenadiary.com

サンプリングするシェーダを書く

次にこれをサンプリングするシェーダを記述します。

Shader "Texture3DExample"
{
    Properties
    {
        _3DTex ("3DTexture", 3D) = "" {}
        _Depth ("Depth", Range(0, 1)) = 0.0
    }

    SubShader
    {
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "IgnoreProjector" = "True"
        }

        Pass
        {
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma require 2darray

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float3 uv : TEXCOORD0;
            };

            TEXTURE3D(_3DTex);
            SAMPLER(sampler_3DTex);
            float4 _3DTex_ST;
            float _Depth;

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv.xy = TRANSFORM_TEX(IN.uv, _3DTex);
                OUT.uv.z = _Depth;
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                return SAMPLE_TEXTURE3D(_3DTex, sampler_3DTex, IN.uv);
            }
            ENDHLSL
        }
    }
}

Texture3D用の各種マクロが用意されているのでそれを使用しています。
URPに対応したシェーダの基本的な書き方については以下の記事を参照してください。

light11.hatenadiary.com

結果

今回は以下のテクスチャをTexture3Dにして上記のシェーダにセットしました。

f:id:halya_11:20210816201155p:plain
元のテクスチャ

_Depthを動かした結果は以下の通りです。

f:id:halya_11:20210816214600g:plain
結果

正常にサンプリングできていることを確認できました。

関連

light11.hatenadiary.com

参考

docs.unity3d.com

docs.unity3d.com