質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

Q&A

解決済

1回答

1971閲覧

Unityのモザイクシェーダーでブロックが正方形にならない

yrema

総合スコア287

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

0グッド

0クリップ

投稿2022/05/28 11:59

モザイクシェーダーを導入したのですが、モザイクが正方形ブロックにならなくて困っています。
下図のように横に長いブロックになってしまいます。
イメージ説明

シェーダーの出どころはこちらです(フリー素材)
https://booth.pm/ja/items/1703064

各インスペクターです。
イメージ説明

イメージ説明

イメージ説明

※Canvasのサイズは120x90、Gameタブの解像度も120x90です。

元画像はこちらです(120x90)
イメージ説明

使用しているのはモザイク1なので
以下のHLSLでは恐らく★1~3の3行をどうにか修正すればいいのではないかと推測しますが、分からなくて困っています。

Shader "Pya/mosaic" { Properties { [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 0 [KeywordEnum(mosaic1_normal, mosaic2_average, blur1_normal, blur2_gauss)] _Mode("Type", Float) = 0 [Header(Mosaic)] _Pixelation ("Pixelation Size", Range(1, 1000)) = 70 [Space (7)] [Header(Blur)] _BlockSize ("Block Size", Range(1, 1000)) = 10 _SD ("SD(blur2 only)", Range(1,100)) = 10 } SubShader { Tags { "Queue" = "Transparent" "RenderType"="Transparent" } ZWrite Off Cull [_Cull] //GrabPassでレンダリング結果を取得 GrabPass {} //X方向へのぼかし処理 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _MODE_MOSAIC1_NORMAL _MODE_MOSAIC2_AVERAGE _MODE_BLUR1_NORMAL _MODE_BLUR2_GAUSS #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float4 grabPos : TEXCOORD0; }; sampler2D _GrabTexture; float4 _GrabTexture_ST; float4 _GrabTexture_TexelSize; float _Pixelation; float _BlockSize; float _SD; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.grabPos = ComputeGrabScreenPos(o.vertex); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 col; float2 uv = i.grabPos.xy / i.grabPos.w; //0~1に変換 // ★1 float2 uv_pixel = floor(uv * _Pixelation) /_Pixelation; //ピクセル化 // ★2 //-----モザイク1 先頭ピクセルで範囲を塗りつぶす --------// #ifdef _MODE_MOSAIC1_NORMAL col = tex2D(_GrabTexture, uv_pixel); // ★3 //-----モザイク2 平均化した色で範囲を塗りつぶす --------// #elif _MODE_MOSAIC2_AVERAGE float count=0; //X方向にピクセルをずらして色を加算する for(int j = 0; j <= floor(1/(_GrabTexture_TexelSize.x * _Pixelation)); j++) { col = col + tex2D(_GrabTexture, uv_pixel + float2(j * _GrabTexture_TexelSize.x, 0)); count++; } //平均 col = col / count; //-----ぼかし1 周辺ピクセルの色を平均化 -------------// #elif _MODE_BLUR1_NORMAL float count=0; float size=floor(_BlockSize)*0.1; for(int j = -size; j <= size; j++) { //X方向にピクセルをずらして色を加算する col = col + tex2D(_GrabTexture, uv + float2(j * _GrabTexture_TexelSize.x,0)); count++; } //平均 col = col / count; //-----ぼかし2 ガウス関数での重み付け --------------// #elif _MODE_BLUR2_GAUSS float size=floor(_BlockSize)*0.1; float weight_total; float var = pow(_SD, 2) * 0.001; //分散 for(int j = -size; j <= size; j++) { float distance = j / size; //重み y = -exp(-0.5*x^2/σ^2) float weight = exp(-0.5 * pow(distance, 2) / var); weight_total = weight_total + weight; //X方向にピクセルをずらして重み付けした色を加算する col = col + tex2D(_GrabTexture, uv + float2(j * _GrabTexture_TexelSize.x,0)) * weight; } //正規化 col = col / weight_total; #endif return col; } ENDCG } //GrabPassで1つ目のPassのレンダリング結果を取得 GrabPass {} //Y方向へのぼかし処理 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _MODE_MOSAIC1_NORMAL _MODE_MOSAIC2_AVERAGE _MODE_BLUR1_NORMAL _MODE_BLUR2_GAUSS #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float4 grabPos : TEXCOORD0; }; sampler2D _GrabTexture; float4 _GrabTexture_ST; float4 _GrabTexture_TexelSize; float _BlockSize; float _SD; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.grabPos = ComputeGrabScreenPos(o.vertex); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 col; float2 uv = i.grabPos.xy / i.grabPos.w; //0~1に変換 #ifdef _MODE_MOSAIC1_NORMAL //何もしない col = tex2D(_GrabTexture, uv); #elif _MODE_MOSAIC2_AVERAGE //何もしない col = tex2D(_GrabTexture, uv); #elif _MODE_BLUR1_NORMAL float count=0; float size=floor(_BlockSize)*0.1; for(int j = -size; j <= size; j++) { //Y方向にピクセルをずらして色を加算する col = col + tex2D(_GrabTexture, uv + float2(0,j * abs(_GrabTexture_TexelSize.y))); count++; } col = col / count; #elif _MODE_BLUR2_GAUSS float size=floor(_BlockSize)*0.1; float weight_total; float var = pow(_SD, 2) * 0.001; for(int j = -size; j <= size; j++) { float distance = j / size; float weight = exp(-0.5 * pow(distance, 2) / var); weight_total = weight_total + weight; //Y方向にピクセルをずらして色を加算する col = col + tex2D(_GrabTexture, uv + float2(0,j * abs(_GrabTexture_TexelSize.y))) * weight; } col = col / weight_total; #endif return col; } ENDCG } } }

◆環境
Unity2020.3.11f1
Windows10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ご注目なさったポイントは適切だと思います。以前別の方の「ドットシェーダーの適用後画像で色がブレンドされてしまう」とのご質問に回答しました折に、おまけとしてモザイクを正方形化することについて検討してみたのですが、それと同様の方法が使えそうです。

シェーダーコードを下記のようにしてみるとどうでしょうか。変更を加えた部分に★マーク付きのコメントを入れました。

ShaderLab

1Shader "Pya/mosaic" { 2 Properties { 3 [HideInInspector] _MainTex ("Texture", 2D) = "white" {} // ★UI用マテリアルにしたとき、_MainTexがないとエラーが表示されてうっとうしいため追加 4 [Enum(UnityEngine.Rendering.CullMode)] 5 _Cull("Cull", Float) = 0 6 [KeywordEnum(mosaic1_normal, mosaic2_average, blur1_normal, blur2_gauss)] _Mode("Type", Float) = 0 7 [Header(Mosaic)] 8 _Pixelation ("Pixelation Size", Range(1, 1000)) = 70 9 [Toggle(SQUARE_PIXEL)] _SquarePixel("Square Pixel", Float) = 0.0 // ★ピクセルを正方形にするかどうかのトグルを追加 10 [Space (7)] 11 [Header(Blur)] 12 _BlockSize ("Block Size", Range(1, 1000)) = 10 13 _SD ("SD(blur2 only)", Range(1,100)) = 10 14 } 15 16 SubShader { 17 Tags { 18 "Queue" = "Transparent" 19 "RenderType"="Transparent" 20 } 21 ZWrite Off 22 Cull [_Cull] 23 24 //GrabPassでレンダリング結果を取得 25 GrabPass {} 26 27 //X方向へのぼかし処理 28 Pass { 29 30 CGPROGRAM 31 #pragma vertex vert 32 #pragma fragment frag 33 #pragma multi_compile _MODE_MOSAIC1_NORMAL _MODE_MOSAIC2_AVERAGE _MODE_BLUR1_NORMAL _MODE_BLUR2_GAUSS 34 #pragma multi_compile _ SQUARE_PIXEL // ★SQUARE_PIXELあり・なしでマルチコンパイル 35 #include "UnityCG.cginc" 36 37 struct appdata { 38 float4 vertex : POSITION; 39 }; 40 41 struct v2f { 42 float4 vertex : SV_POSITION; 43 float4 grabPos : TEXCOORD0; 44 }; 45 46 sampler2D _GrabTexture; 47 float4 _GrabTexture_ST; 48 float4 _GrabTexture_TexelSize; 49 float _Pixelation; 50 float _BlockSize; 51 float _SD; 52 53 v2f vert(appdata v) { 54 v2f o; 55 o.vertex = UnityObjectToClipPos(v.vertex); 56 o.grabPos = ComputeGrabScreenPos(o.vertex); 57 return o; 58 } 59 60 fixed4 frag(v2f i) : SV_Target { 61 fixed4 col; 62 float2 uv = i.grabPos.xy / i.grabPos.w; //0~1に変換 63 64 // ★SQUARE_PIXELがオンの場合、アスペクト比に応じて水平方向のピクセル数を増やす 65 #ifdef SQUARE_PIXEL 66 // ★座標系の反転がある場合_GrabTexture_TexelSize.yが負になるので、それを考慮してabsを併用する 67 float2 pixelation = float2(_GrabTexture_TexelSize.z * abs(_GrabTexture_TexelSize.y) * _Pixelation, _Pixelation); 68 #else 69 float2 pixelation = _Pixelation; 70 #endif 71 72 // ★_Pixelationの代わりにpixelationを使う 73 float2 uv_pixel = floor(uv * pixelation) / pixelation; //ピクセル化 74 75 //-----モザイク1 先頭ピクセルで範囲を塗りつぶす --------// 76 #ifdef _MODE_MOSAIC1_NORMAL 77 col = tex2D(_GrabTexture, uv_pixel); 78 79 //-----モザイク2 平均化した色で範囲を塗りつぶす --------// 80 #elif _MODE_MOSAIC2_AVERAGE 81 // ★_Pixelationの代わりにpixelationを使う 82 // ★式もちょっと変更 83 int count = (int)max(1.0, _GrabTexture_TexelSize.z / pixelation.x); 84 col = tex2D(_GrabTexture, uv_pixel); 85 //X方向にピクセルをずらして色を加算する 86 for(int j = 1; j < count; j++) { 87 col += tex2D(_GrabTexture, uv_pixel + float2(j * _GrabTexture_TexelSize.x, 0)); 88 } 89 //平均 90 col = col / count; 91 92 //-----ぼかし1 周辺ピクセルの色を平均化 -------------// 93 #elif _MODE_BLUR1_NORMAL 94 float count=0; 95 float size=floor(_BlockSize)*0.1; 96 for(int j = -size; j <= size; j++) { 97 //X方向にピクセルをずらして色を加算する 98 col = col + tex2D(_GrabTexture, uv + float2(j * _GrabTexture_TexelSize.x,0)); 99 count++; 100 } 101 //平均 102 col = col / count; 103 104 //-----ぼかし2 ガウス関数での重み付け --------------// 105 #elif _MODE_BLUR2_GAUSS 106 float size=floor(_BlockSize)*0.1; 107 float weight_total; 108 float var = pow(_SD, 2) * 0.001; //分散 109 110 for(int j = -size; j <= size; j++) { 111 float distance = j / size; 112 //重み y = -exp(-0.5*x^2/σ^2) 113 float weight = exp(-0.5 * pow(distance, 2) / var); 114 weight_total = weight_total + weight; 115 //X方向にピクセルをずらして重み付けした色を加算する 116 col = col + tex2D(_GrabTexture, uv + float2(j * _GrabTexture_TexelSize.x,0)) * weight; 117 } 118 //正規化 119 col = col / weight_total; 120 121 #endif 122 123 return col; 124 } 125 126 ENDCG 127 } 128 129 //GrabPassで1つ目のPassのレンダリング結果を取得 130 GrabPass {} 131 132 //Y方向へのぼかし処理 133 Pass { 134 135 CGPROGRAM 136 #pragma vertex vert 137 #pragma fragment frag 138 #pragma multi_compile _MODE_MOSAIC1_NORMAL _MODE_MOSAIC2_AVERAGE _MODE_BLUR1_NORMAL _MODE_BLUR2_GAUSS 139 #include "UnityCG.cginc" 140 141 struct appdata { 142 float4 vertex : POSITION; 143 }; 144 145 struct v2f { 146 float4 vertex : SV_POSITION; 147 float4 grabPos : TEXCOORD0; 148 }; 149 150 sampler2D _GrabTexture; 151 float4 _GrabTexture_ST; 152 float4 _GrabTexture_TexelSize; 153 float _BlockSize; 154 float _SD; 155 156 v2f vert(appdata v) { 157 v2f o; 158 o.vertex = UnityObjectToClipPos(v.vertex); 159 o.grabPos = ComputeGrabScreenPos(o.vertex); 160 return o; 161 } 162 163 fixed4 frag(v2f i) : SV_Target { 164 fixed4 col; 165 float2 uv = i.grabPos.xy / i.grabPos.w; //0~1に変換 166 167 #ifdef _MODE_MOSAIC1_NORMAL 168 //何もしない 169 col = tex2D(_GrabTexture, uv); 170 #elif _MODE_MOSAIC2_AVERAGE 171 //何もしない 172 col = tex2D(_GrabTexture, uv); 173 #elif _MODE_BLUR1_NORMAL 174 float count=0; 175 float size=floor(_BlockSize)*0.1; 176 for(int j = -size; j <= size; j++) { 177 //Y方向にピクセルをずらして色を加算する 178 col = col + tex2D(_GrabTexture, uv + float2(0,j * abs(_GrabTexture_TexelSize.y))); 179 count++; 180 } 181 col = col / count; 182 #elif _MODE_BLUR2_GAUSS 183 float size=floor(_BlockSize)*0.1; 184 float weight_total; 185 float var = pow(_SD, 2) * 0.001; 186 187 for(int j = -size; j <= size; j++) { 188 float distance = j / size; 189 float weight = exp(-0.5 * pow(distance, 2) / var); 190 weight_total = weight_total + weight; 191 //Y方向にピクセルをずらして色を加算する 192 col = col + tex2D(_GrabTexture, uv + float2(0,j * abs(_GrabTexture_TexelSize.y))) * weight; 193 } 194 col = col / weight_total; 195 #endif 196 return col; 197 } 198 199 ENDCG 200 } 201 } 202 203}

投稿2022/05/28 21:39

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yrema

2022/05/28 21:44

早速試してみました。期待通りのモザイクが出てきました! すごいです!尊敬します!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問