3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

波打つUVでぷるぷる背景を作る

Last updated at Posted at 2025-08-28

はじめに

「HLSLって難しそう…」と思っていたけど、実は短いコードで動く表現が作れると知りました。
今回は、テクスチャを水面のように波打たせるシェーダーを作ります。
影やライティングは一切なし、Unlitでシンプルに。

環境

  • Unity 6 (6000.0.28f1) LTS
  • Universal Render Pipeline(URP 3D テンプレート)
  • 素材は水面やスライムっぽい模様のテクスチャ(模様がある方が動きが分かりやすい)

完成イメージ

Videotogif.gif

実装手順

1. シェーダーを作成

今回はUnlitShaderを作成します。

Shader "Unlit/WaveUV_URP" // シェーダーの名前(マテリアル作成時に選択するパス)
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {} // メインテクスチャ(波打たせる画像)
        _Amplitude ("Wave Amplitude", Float) = 0.05 // 波の振幅(揺れの大きさ)
        _Frequency ("Wave Frequency", Float) = 10.0 // 波の周波数(1単位あたりの波の数)
        _Speed ("Wave Speed", Float) = 2.0 // 波の速度
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline" // URPでのみ使用可能
            "RenderType"="Opaque" // 不透明オブジェクトとして描画
            "Queue"="Geometry" // 描画順序(ジオメトリキュー)
        }

        Pass
        {
            Name "Unlit" // パスの名前(任意)
            HLSLPROGRAM // HLSLコードの開始
            #pragma vertex   vert // 頂点シェーダー関数の指定
            #pragma fragment frag // フラグメントシェーダー関数の指定
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // URPの基本関数や定義を読み込み

            // 頂点シェーダーに渡される入力構造体
            struct Attributes {
                float4 positionOS : POSITION; // オブジェクト空間の頂点座標
                float2 uv         : TEXCOORD0; // メッシュのUV座標
            };

            // 頂点シェーダーからフラグメントシェーダーに渡すデータ
            struct Varyings {
                float2 uv         : TEXCOORD0; // 変形後のUV座標
                float4 positionHCS: SV_POSITION; // クリップ空間の頂点座標
            };

            // テクスチャとサンプラーの宣言(URP推奨の書き方)
            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);

            // マテリアルごとの定数バッファ(SRP Batcher対応)
            CBUFFER_START(UnityPerMaterial)
                float4 _MainTex_ST; // TilingとOffset(_MainTexの設定から自動で渡される)
                float  _Amplitude;  // 波の振幅
                float  _Frequency;  // 波の周波数
                float  _Speed;      // 波の速度
            CBUFFER_END

            // 頂点シェーダー
            Varyings vert (Attributes v)
            {
                Varyings o;
                o.positionHCS = TransformObjectToHClip(v.positionOS); // オブジェクト空間座標をクリップ空間に変換
                float2 uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw; // TilingとOffsetを適用したUV

                // URPでは _TimeParameters.y が経過秒(Built-inの _Time.y と同等)
                uv.y += sin(uv.x * _Frequency + _TimeParameters.y * _Speed) * _Amplitude; // 波打ちUVの計算
                o.uv = uv; // 計算後のUVを出力にセット
                return o;
            }

            // フラグメントシェーダー
            half4 frag (Varyings i) : SV_Target
            {
                return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); // UVに基づいてテクスチャをサンプリングして色を返す
            }
            ENDHLSL // HLSLコードの終了
        }
    }
}

2. マテリアルを作成

アテリアルを作成し、先ほど作ったシェーダーをマテリアルで選択します。

スクリーンショット 2025-08-22 9.42.29.png

  • _MainTex に模様のあるテクスチャを設定(水面やスライム模様がおすすめ)
  • _Amplitude:0.08〜0.12
  • _Frequency:8〜12
  • _Speed:2〜4
  • PlayモードでGameビューを確認

3. Quadにマテリアルをアタッチ

スクリーンショット 2025-08-22 9.48.41.png

応用例

  • 縦波uv.xuv.y を入れ替える
  • 二重波sin を2本足して干渉感を出す
  • 色のゆらぎcol.rgb *= 0.9 + 0.1 * sin(_Time.y * 2.0);
    ※ frag 内で追加

まとめ

  • HLSLは「UVをちょっといじる」だけで動きのある表現が作れる

  • 単色より模様のあるテクスチャの方が変化が分かりやすい

  • 次は色変化やフェードなども組み合わせてみたい

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?