URP向けのモザイクシェーダーを作ってみたメモ。ブロックサイズ指定で粗さを変更など

URP モザイク シェーダー unityスクリプト
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^_^*)

この記事はURP向けのモザイクシェーダーを作ってみたのでそれについての記事です。

GIFアニメにモザイクをかける方法もあるので、興味がある方はどうぞ。

●PRスペース●

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

作ったきっかけ:URPはカスタムシェーダーが作りやすくなったと聞いたのでChatGPTに書いてもらった

ChatGPTにURPについて聞いていたらそんなことを言っていたので試しに書かせてみただけです。

URP モザイク シェーダー

まぁモザイクならエロいやつに使えるだろうと思い…w

シェーダーファイルの作成手順

ChatGPT便利すぎますね…。

URP モザイク シェーダー
ChatGPT
ChatGPT

HLSL(シェーダー言語)の場合、C#のように .cs ではなく、 .shader ファイルを作成して記述します。
手順は以下の通りです!

① 新しいシェーダーファイルを作る

  1. UnityのプロジェクトウィンドウAssets フォルダを右クリック
  2. Create > Shader > Unlit Shader を選択(または Create > Shader > URP > Unlit Shader
  3. 作成された .shader ファイルの名前を MosaicShader.shader に変更

② シェーダーコードを記述

作成した .shader ファイルを開き、以下のコードを貼り付けます。

Shader "Custom/MosaicGlass"
{
    Properties
    {
        _BlockSize ("Block Size", Range(0.0, 0.1)) = 0.05  
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

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

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

            // カメラの背景テクスチャ
            TEXTURE2D(_CameraOpaqueTexture);
            SAMPLER(sampler_CameraOpaqueTexture);

            float _BlockSize;

            Varyings vert (Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = IN.uv;
                return OUT;
            }

            half4 frag (Varyings IN) : SV_Target
            {
                // スクリーン座標系でのUV取得
                float2 screenUV = IN.positionHCS.xy / _ScreenParams.xy;

                // モザイク処理
                float2 blockUV = floor(screenUV / _BlockSize) * _BlockSize;
                half4 color = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, blockUV);

                // BlockSize が 0 の場合は完全透明
                color.a = step(0.01, _BlockSize);

                return color;
            }
            ENDHLSL
        }
    }
}

③ マテリアルを作成してシェーダーを適用

  1. 新しいマテリアル を作成(Create > Material
  2. Shader の欄を Custom/MosaicGlass に変更
  3. _BlockSize の値を調整(例: 0.05 で適度なモザイク効果)

🔹 これでモザイクシェーダーが完成!

  • _BlockSize を大きくすると 荒いモザイク、小さくすると 細かいモザイク になります。
  • URPで動作 し、シェーダーグラフなしで .shader ファイルだけでOK!💡

この方法で、モザイクエフェクトをURPで実装 できます!🎨

実際に作ってみる

私はシェーダーなんて作ったことがないため、ChatGPT氏の言うとおりにやってみます。

シェーダーファイルを作ってコードをコピペする

右クリック ⇒ 作成 ⇒ シェーダー ⇒ Unlitシェーダー で作成し、コードをコピペする。

マテリアルを作ってシェーダーを設定、適当なオブジェクトに割り当てればOK。

あとは位置とBlockサイズを調整すれば使えます。

追記:BIRP向けのも作ってみた

Unity6000.0.32で動作確認しました。

これも 右クリック ⇒ 作成 ⇒ シェーダー ⇒ Unlitシェーダー で作成し、コードをコピペすればOK。

Shader "Custom/MosaicGlass_BIRP"
{
    Properties
    {
        _BlockSize ("Block Size", Range(0.0, 0.1)) = 0.05
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off
        ZWrite Off

        GrabPass { "_GrabTexture" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _GrabTexture;
            float _BlockSize;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 grabUV : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.grabUV = ComputeGrabScreenPos(o.pos); // ★ 安定したスクリーンUV計算
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 正規化されたスクリーンUV(除算付き)
                float2 screenUV = i.grabUV.xy / i.grabUV.w;

                // モザイク処理
                float2 blockUV = floor(screenUV / _BlockSize) * _BlockSize;
                fixed4 col = tex2D(_GrabTexture, blockUV);

                // BlockSize が小さすぎる場合は透明に
                col.a = step(0.01, _BlockSize);
                return col;
            }
            ENDCG
        }
    }
}

おわりに

案外簡単にできて良かった。

ChatGPTマジで便利ですね…。

また何かあれば追記します(*^_^*)

タイトルとURLをコピーしました