Unity Custom Shader 記述におけるテクスチャの扱い (URP 環境)

Unity シェーダーの勉強.
テクスチャ周りについて覚え書き.
頂点シェーダー, フラグメントシェーダーについての基礎は 過去の記事 を参照のこと.

検証環境

テクスチャの宣言回り

テクスチャを各種シェーダー内で使用するには

  1. プロパティブロックにおける _BaseMap の宣言
  2. 各種構造体における uv 変数の宣言
  3. _BaseMap とサンプラーの宣言

が必要となる

プロパティブロックにおける _BaseMap の宣言

Properties
{
    [MainTexture] _BaseMap("Base Map", 2D) = "white"
}
        

各種構造体における uv 変数の宣言

struct Attributes
{
    // vertices position of object space
    float4 positionOS   : POSITION;

    // uv position
    float2 uv : TEXCOORD0;
};

struct Varyings
{
    // vertices position of screen space
    float4 positionHCS  : SV_POSITION;

    // uv position
    float2 uv : TEXCOORD0;
};
        

_BaseMap とサンプラーの宣言

// declear basemap
TEXTURE2D(_BaseMap);

// declear sampler
SAMPLER(sampler_BaseMap);

// basemap for frag
CBUFFER_START(UnityPerMaterial)
    float4 _BaseMap_ST;
CBUFFER_END
        

タイリングやオフセットの処理

// set uv position
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
        
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
        

サンプリングについて

half4 color = SAMPLE_TEXTURE2D(texture, sampler, uv);
        

オブジェクトへの適用

Shader "TextureTile/URPUnlitShaderBasic"
{
    Properties
    {
        [MainTexture] _BaseMap("Base Map", 2D) = "white"
    }

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

        Pass
        {
            HLSLPROGRAM
            
            #pragma vertex vert
            
            #pragma fragment frag

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

            struct Attributes
            {
                // vertices position of object space
                float4 positionOS   : POSITION;

                // uv position
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                // vertices position of screen space
                float4 positionHCS  : SV_POSITION;

                // uv position
                float2 uv : TEXCOORD0;
            };

            // declear basemap
            TEXTURE2D(_BaseMap);

            // declear sampler
            SAMPLER(sampler_BaseMap);

            // basemap for frag
            CBUFFER_START(UnityPerMaterial)
                float4 _BaseMap_ST;
            CBUFFER_END

            // vertex shader
            Varyings vert(Attributes IN)
            {
                // output object
                Varyings OUT;

                // position change with noise
                float3 outPos = IN.positionOS.xyz;

                // to clip space
                OUT.positionHCS = TransformObjectToHClip(outPos);

                // set uv position
                OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);

                return OUT;
            }

            // fragment shader
            half4 frag(Varyings IN) : SV_Target
            {
                // sampling texture and get color
                half4 textureColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
                return textureColor;
            }
            ENDHLSL
        }
    }
}
        

(おまけ) テクスチャを時間とともに動かす

// set uv position
float2 outUv = TRANSFORM_TEX(IN.uv, _BaseMap);
float speed = 10.0;
outUv.x += _Time.x * speed;
outUv.y += _Time.x * speed;

OUT.uv = outUv;
        

move text gif