docs.unity3d.com
    目次を表示する/隠す

    カスタムの Terrain ツールシェーダー

    ビルトインのペインティングマテリアルを使用しない場合は、独自のシェーダーを作成する必要があります。作成後はそのシェーダーを使用してマテリアルを作成し、代わりにそのマテリアルを使用して Terrain (地形) テクスチャデータを変更できます。

    以下は Terrain ツールシェーダーの例です。

    Shader "TerrainTool/CustomTerrainTool"
    {
        Properties { _MainTex ("Texture", any) = "" {} }
    
        SubShader
        {
            ZTest Always Cull Off ZWrite Off
    
            HLSLINCLUDE
    
            #include "UnityCG.cginc"
            #include "Packages/com.unity.terrain-tools/Shaders/TerrainTools.hlsl"
    
            sampler2D _MainTex;
            float4 _MainTex_TexelSize;      // 1/width、1/height、width、height
    
            sampler2D _BrushTex;
    
            float4 _BrushParams;
            #define BRUSH_STRENGTH      (_BrushParams[0])
            #define BRUSH_TARGETHEIGHT  (_BrushParams[1])
            #define kMaxHeight          (32766.0f/65535.0f)
    
            struct appdata_t
            {
                float4 vertex : POSITION;
                float2 pcUV : TEXCOORD0;
            };
    
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 pcUV : TEXCOORD0;
            };
    
            v2f vert(appdata_t v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.pcUV = v.pcUV;
                return o;
            }
    
            ENDHLSL
    
            Pass
            {
                Name "CustomTerrainTool"
    
                HLSLPROGRAM
    
                #pragma vertex vert
                #pragma fragment frag
    
                float4 frag(v2f i) : SV_Target
                {
                    float2 brushUV = PaintContextUVToBrushUV(i.pcUV);
    
                    // 境界外の乗数
                    float oob = all(saturate(brushUV) == brushUV) ? 1.0f : 0.0f;
    
                    // ソースのハイトマップテクスチャの領域となる MainTex をサンプリングし、指定された UV での現在の高さの値を取得します
                    // ここでは UnpackHeightmap が必要になります。UnpackHeightmap は、現在のプラットフォームやグラフィックスデバイスが R16_UNorm テクスチャフォーマットに対応していない場合に、高さの値を R および G チャンネルからアンパックするためです。R16_UNorm フォーマットに対応している場合は、R チャンネルのみから読み取りを行います
                    float height = UnpackHeightmap(tex2D(_MainTex, i.pcUV));
                    // このフラグメントでのブラシマスクの影響度を計算します
                    float brushShape = oob * UnpackHeightmap(tex2D(_BrushTex, brushUV));
                    // 新しい高さの値を計算します
                    height = height + BRUSH_STRENGTH * brushShape;
    
                    // 書き込み先の RenderTexture に新しい高さを格納します。ハイトマップ自体は符号付きですが、Terrain のレンダリング時に符号なしのテクスチャとして処理されるため、0.0f と 0.5f の間で固定します
                    // ここでは PackHeightmap が必要です。PackHeightmap は、現在のプラットフォームやグラフィックスデバイスが R16_UNorm テクスチャフォーマットに対応していない場合に、高さの値を R および G チャンネルにパックするためです。R16_UNorm フォーマットに対応している場合、R チャンネルのみに書き込みを行います
                    return PackHeightmap(clamp(height, 0, kMaxHeight));
                }
    
                ENDHLSL
            }
        }
    }
    
    トップに戻る
    Copyright © 2023 Unity Technologies — 商標と利用規約
    • 法律関連
    • プライバシーポリシー
    • クッキー
    • 私の個人情報を販売または共有しない
    • Your Privacy Choices (Cookie Settings)