気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
まず透明度が反映されない件については、frag
末尾のreturn col;
の手前でcol.a = alpha;
という風に元の画像のアルファを無視して新しいアルファで上書きしていることによるかと思います。ここをcol.a *= alpha;
に変更して、元のアルファと角丸アルファの積を最終的なアルファとして出力させればいいんじゃないでしょうか。
ご質問者さんのボタン画像をまねて下記のような画像を作り...
修正を加えたシェーダーで、Radius pxを1~92に変化させたところ下図のようになりました。
もし内側の境界も丸めたいとなると、テクスチャのサンプリング位置をずらしてむりやり丸くひずめてやることになりそうです。
RoundedRect.shaderを複製し、さしあたり名前は「RoundedRectWarp.shader」として、内容は下記のように変更したところ...
ShaderLab
1Shader "Custom/2D/RoundedRectWarp" { 2Properties { 3 _MainTex ("Texture", 2D) = "white" {} 4 _Radius ("Radius px", Float) = 10 5 _Width ("Width px", Float) = 100 6 _Height ("Height px", Float) = 100 7 8 // おまけ...ソフトエッジを使うかどうかをトグルで切り替えるようにする 9 [Toggle(SOFT_EDGE)] _SoftEdge("Soft edge", Float) = 0 10 11 // required for UI.Mask 12 [HideInInspector] _StencilComp ("Stencil Comparison", Float) = 8 13 [HideInInspector] _Stencil ("Stencil ID", Float) = 0 14 [HideInInspector] _StencilOp ("Stencil Operation", Float) = 0 15 [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255 16 [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255 17 [HideInInspector] _ColorMask ("Color Mask", Float) = 15 18} 19SubShader { 20 Tags { 21 "RenderType"="Transparent" 22 "Queue"="Transparent" 23 } 24 25 // required for UI.Mask 26 Stencil 27 { 28 Ref [_Stencil] 29 Comp [_StencilComp] 30 Pass [_StencilOp] 31 ReadMask [_StencilReadMask] 32 WriteMask [_StencilWriteMask] 33 } 34 35 Cull Off 36 Lighting Off 37 ZTest [unity_GUIZTestMode] 38 39 // Alpha blending. 40 ZWrite Off 41 Blend SrcAlpha OneMinusSrcAlpha 42 43 Pass { 44 CGPROGRAM 45 #pragma vertex vert 46 #pragma fragment frag 47 48 // SOFT_EDGEなし・ありでマルチコンパイル 49 #pragma multi_compile _ SOFT_EDGE 50 51 #include "UnityCG.cginc" 52 53 struct appdata { 54 float4 vertex : POSITION; 55 float2 uv : TEXCOORD0; 56 float4 color : COLOR; 57 }; 58 59 struct v2f { 60 float2 uv : TEXCOORD0; 61 float4 vertex : SV_POSITION; 62 float4 color : COLOR; 63 }; 64 65 sampler2D _MainTex; 66 float4 _MainTex_ST; 67 float _Radius; 68 float _Width; 69 float _Height; 70 71 v2f vert (appdata v) { 72 v2f o; 73 o.vertex = UnityObjectToClipPos(v.vertex); 74 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 75 o.color = v.color; 76 return o; 77 } 78 79 float MakeEdge(float from, float to, fixed t) { 80 fixed r = max(_Radius, 2); 81 t = saturate(t * (r - t)); 82 return lerp(from, to, t); 83 } 84 85 86 float2 GetRadiusToPointVector(float2 pixel, float2 halfRes, float radius) { 87 float2 firstQuadrant = abs(pixel); 88 float2 radiusToPoint = firstQuadrant - (halfRes - radius); 89 radiusToPoint = max(radiusToPoint, 0.0); 90 return radiusToPoint; 91 } 92 93 float SoftRounded(float2 pixel, float2 halfRes, float radius) { 94 float2 v = GetRadiusToPointVector(pixel, halfRes, radius); 95 float alpha = 1.0 - length(v) / radius; 96 alpha = MakeEdge(0, 1, alpha); 97 return alpha; 98 } 99 100 float HardRounded(float2 pixel, float2 halfRes, float radius) { 101 float2 v = GetRadiusToPointVector(pixel, halfRes, radius); 102 float alpha = 1.0 - floor(length(v) / radius); 103 return alpha; 104 } 105 106 fixed4 frag (v2f i) : SV_Target { 107 float2 uvInPixel = (i.uv - 0.5) * float2(_Width, _Height); 108 float2 halfRes = float2(_Width, _Height) * 0.5; 109 110 // SOFT_EDGEの有無によって関数を切り替える 111 #ifdef SOFT_EDGE 112 float alpha = SoftRounded(uvInPixel, halfRes, _Radius); 113 #else 114 float alpha = HardRounded(uvInPixel, halfRes, _Radius); 115 #endif 116 117 // まず角の丸め部分の中心を基準とした座標を得て... 118 float2 v = GetRadiusToPointVector(uvInPixel, halfRes, _Radius); 119 120 // 丸め部分は45°の直線に対して対称なので、話を簡単にするためその直線で折り返して... 121 float2 foldedV = float2(max(v.x, v.y), min(v.x, v.y)); 122 123 // 丸め領域内であるならば... 124 if (foldedV.y > 0.0) { 125 // 丸め部分中心と注目ピクセルを結ぶ線分を最外周まで延長し 126 // その衝突点と丸め部分中心との距離を求め... 127 float l = length(float2(_Radius, foldedV.y * _Radius / foldedV.x)); 128 129 // 半径に対するその距離の割合だけテクスチャサンプリング位置をずらす 130 float2 newUvInPixel = uvInPixel + ((l / _Radius) - 1.0) * sign(uvInPixel) * v; 131 i.uv = (newUvInPixel / float2(_Width, _Height)) + 0.5; 132 } 133 134 fixed4 col = tex2D(_MainTex, i.uv) * i.color; 135 136 // col.aは上書きでなく乗算代入とし、元画像のアルファも反映させる 137 col.a *= alpha; 138 139 return col; 140 } 141 ENDCG 142 } 143} 144}
これを使ったマテリアルに変えて、Radius pxを1~92に変化させたところ下図のようになりました。
投稿2019/12/20 22:54
総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/21 03:57