いつも調べてみては、良いリファレンスを見つけられずalphaの値を変えてごまかしている部分なのですが、
レイヤーにグラデーションオーバーレイをかけて塗り○%が設定されているデザインをUnity uGUIのシェーダーで近い表現にしたいと思ったら、どうすれば良いかイマイチよくわからないです。
Photoshop”塗り○%”:レイヤースタイル効果の不透明度は維持したまま、本体の不透明度を下げる設定。
上の画像は、レイヤーにレイヤースタイルのグラデーションオーバーレイ(カラー1:青,不透明度80%、カラー2:紫,不透明度60%)をかけたものです。
2は不透明度、3は塗りの設定を同じ値で調整したときの見え方になります。
Unityで普通にalpha値でやるとおそらく2になってしまうかと思うのですが、見え方的には極力3に近しいものにしたいです。
なにか良い方法あれば、ご教授いただきたいです...!
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/09 06:10
回答2件
0
ベストアンサー
「まだ回答を求めています」が付いているようでしたので、私もちょっとやってみることにしました。
いろいろいじっていた結果、下記のような形のものができました。
ShaderLab
1Shader "UI/Gradient Overlay" 2{ 3 Properties 4 { 5 [PerRendererData] _MainTex ("Texture", 2D) = "white" {} 6 7 [Header(Layer)] 8 _Opacity ("Opacity", Range(0.0, 1.0)) = 1.0 9 _Fill ("Fill", Range(0.0, 1.0)) = 1.0 10 11 [Header(Gradient)] 12 _Color1 ("Color1", Color) = (0.3, 0.6, 1.0, 0.8) 13 _Color2 ("Color2", Color) = (0.8, 0.5, 1.0, 0.6) 14 [Toggle] _Reverse ("Reverse", Float) = 0 15 [KeywordEnum(Linear, Radial, Angle, Reflected, Diamond)] _Style ("Style", Float) = 0 16 _Angle ("Angle", Range(0.0, 360.0)) = 0.0 17 _Scale ("Scale", Range(0.1, 1.5)) = 1.0 18 _OffsetX ("Offset X", Range(-0.5, 0.5)) = 0.0 19 _OffsetY ("Offset Y", Range(-0.5, 0.5)) = 0.0 20 21 [Header(UI)] 22 _Color ("Tint", Color) = (1.0, 1.0, 1.0, 1.0) 23 _StencilComp ("Stencil Comparison", Float) = 8 24 _Stencil ("Stencil ID", Float) = 0 25 _StencilOp ("Stencil Operation", Float) = 0 26 _StencilWriteMask ("Stencil Write Mask", Float) = 255 27 _StencilReadMask ("Stencil Read Mask", Float) = 255 28 _ColorMask ("Color Mask", Float) = 15 29 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 30 } 31 32 SubShader 33 { 34 Tags 35 { 36 "Queue"="Transparent" 37 "IgnoreProjector"="True" 38 "RenderType"="Transparent" 39 "PreviewType"="Plane" 40 "CanUseSpriteAtlas"="True" 41 } 42 43 Stencil 44 { 45 Ref [_Stencil] 46 Comp [_StencilComp] 47 Pass [_StencilOp] 48 ReadMask [_StencilReadMask] 49 WriteMask [_StencilWriteMask] 50 } 51 52 Cull Off 53 Lighting Off 54 ZWrite Off 55 ZTest [unity_GUIZTestMode] 56 Blend One OneMinusSrcAlpha 57 ColorMask [_ColorMask] 58 59 Pass 60 { 61 Name "Gradient Overlay" 62 CGPROGRAM 63 #pragma vertex vert 64 #pragma fragment frag 65 66 #include "UnityCG.cginc" 67 #include "UnityUI.cginc" 68 69 #pragma multi_compile_local _ UNITY_UI_CLIP_RECT 70 #pragma multi_compile_local _ UNITY_UI_ALPHACLIP 71 #pragma multi_compile_local _STYLE_LINEAR _STYLE_RADIAL _STYLE_ANGLE _STYLE_REFLECTED _STYLE_DIAMOND 72 73 struct appdata_t 74 { 75 float4 vertex : POSITION; 76 float4 color : COLOR; 77 float2 texcoord : TEXCOORD0; 78 UNITY_VERTEX_INPUT_INSTANCE_ID 79 }; 80 81 struct v2f 82 { 83 float4 vertex : SV_POSITION; 84 fixed4 color : COLOR; 85 float4 texcoord : TEXCOORD0; 86 float4 worldPosition : TEXCOORD1; 87 UNITY_VERTEX_OUTPUT_STEREO 88 }; 89 90 sampler2D _MainTex; 91 fixed4 _Color; 92 fixed4 _TextureSampleAdd; 93 float4 _ClipRect; 94 float4 _MainTex_ST; 95 96 v2f vert(appdata_t v) 97 { 98 v2f OUT; 99 UNITY_SETUP_INSTANCE_ID(v); 100 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 101 OUT.worldPosition = v.vertex; 102 OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); 103 OUT.texcoord = float4(TRANSFORM_TEX(v.texcoord, _MainTex), v.texcoord); 104 OUT.color = v.color * _Color; 105 return OUT; 106 } 107 108 float _Opacity; 109 float _Fill; 110 fixed4 _Color1; 111 fixed4 _Color2; 112 float _Reverse; 113 float _Angle; 114 float _Scale; 115 float _OffsetX; 116 float _OffsetY; 117 118 fixed4 frag(v2f IN) : SV_Target 119 { 120 // グラデーションの形を決める(変数tの値を0~1の範囲で設定する) 121 float2 center = float2(_OffsetX + 0.5, _OffsetY + 0.5); 122 #if _STYLE_RADIAL 123 // 円形 124 float t = distance(center, IN.texcoord.zw) * 2.0; 125 #else 126 float2x2 rotation; 127 sincos(_Angle * UNITY_PI / 180.0, rotation._21, rotation._11); 128 rotation._12_22 = rotation._21_11 * float2(-1.0, 1.0); 129 float2 p = mul(IN.texcoord.zw - center, rotation); 130 131 #if _STYLE_ANGLE 132 // 角度 133 float t = fmod(atan2(p.y, p.x) * UNITY_INV_TWO_PI + 1.0, 1.0); 134 #else 135 #if _STYLE_DIAMOND 136 // 菱形 137 float t = dot(abs(p) * 2.0, 1.0); 138 #else 139 #if _STYLE_REFLECTED 140 // 反射 141 float t = abs(p.x) * 2.0; 142 #else 143 // 線形 144 float t = p.x + 0.5; 145 #endif 146 #endif 147 #endif 148 #endif 149 150 // スケールに応じてtを伸縮させる 151 #if _STYLE_LINEAR 152 t = saturate((t - 0.5) / _Scale + 0.5); 153 #elif _STYLE_ANGLE 154 t = saturate(t); 155 #else 156 t = saturate(t / _Scale); 157 #endif 158 159 // 反転がオンならtを逆転させる 160 t += (1.0 - 2.0 * t) * _Reverse; 161 162 // 色の合成を行う 163 // まずテクスチャ色、グラデーション色を取得して... 164 float4 gradientColor = lerp(_Color1, _Color2, t); 165 float4 textureColor = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; 166 167 // テクスチャ色のRGBのみを取り出し、塗りの強度に応じて弱めたものを下地とし... 168 float4 color = float4(textureColor.rgb, 1.0) * _Fill; 169 170 // グラデーション色を「Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha」方式で重ねて... 171 color.rgb *= 1.0 - gradientColor.a; 172 color.rgb += gradientColor.rgb * gradientColor.a; 173 color.a *= 1.0 - gradientColor.a; 174 color.a += gradientColor.a; 175 176 // 不透明度と元のテクスチャのアルファをかけて... 177 color *= _Opacity * textureColor.a; 178 179 // 矩形クリップを行い... 180 #ifdef UNITY_UI_CLIP_RECT 181 color *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); 182 #endif 183 184 // アルファクリップを行い... 185 #ifdef UNITY_UI_ALPHACLIP 186 clip(color.a - 0.001); 187 #endif 188 189 // できあがった最終的な色を「Blend One OneMinusSrcAlpha」で合成する 190 return color; 191 } 192 ENDCG 193 } 194 } 195}
下図のようなテクスチャをセットした上で...
「Opacity」を操作すると全体の透明度が変化し、「Fill」を操作すると下絵のテクスチャの透明度が変化するような動作になりました。
念のため申し上げますと、私の場合はi_znaさんの案と異なり、「Gradient Overlay」という名前ながら合成方式はオーバーレイになっておりません(よくある通常のアルファブレンディングです)。
Photoshopの機能名の「グラデーションオーバーレイ」というのもおそらく単にグラデーションを上乗せすることを意味しており、エフェクトの合成方法は必ずしもオーバーレイとは限らないようでしたので、それにならったネーミングにしてみました。
コード中の// グラデーション色を「Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha」方式で重ねて...
のあたりを書き換えれば、下絵にグラデーションを重ねる時の合成方法をいろいろな形に変更できるかと思います。
投稿2020/10/17 03:25
総合スコア10811
0
塗り%とはレイヤースタイルを残して本体の透明度を下げるものみたいですが、そもそもUnityにレイヤースタイルはないので作る必要があります。
他の画像でオーバーレイをかけるものだと下のようなものになると思います。
(Overlay.shaderというファイル名で保存してマテリアルにドラッグ&ドロップしてください。)
GLSL
1Shader "Overlay" 2{ 3 Properties 4 { 5 _MainTex("テクスチャ", 2D) = "white" {} 6 _MainTexOpacity ("テクスチャ透明度(塗り)", Range(0, 1)) = 1 7 _OverlayTex("オーバーレイテクスチャ", 2D) = "white" {} 8 _OverlayOpacity ("オーバーレイ透明度", Range(0, 1)) = 1 9 } 10 11 SubShader 12 { 13 Tags { "Queue" = "Transparent" } 14 15 GrabPass 16 { 17 "_BackgroundTexture" 18 } 19 20 Pass 21 { 22 CGPROGRAM 23 #pragma vertex vert 24 #pragma fragment frag 25 #include "UnityCG.cginc" 26 27 struct appdata 28 { 29 float4 vertex : POSITION; 30 float2 uv : TEXCOORD0; 31 }; 32 33 struct v2f 34 { 35 float2 uv : TEXCOORD0; 36 float4 grabPos : TEXCOORD1; 37 float4 pos : SV_POSITION; 38 }; 39 40 sampler2D _MainTex; 41 sampler2D _OverlayTex; 42 float4 _MainTex_ST; 43 sampler2D _BackgroundTexture; 44 float _MainTexOpacity; 45 float _OverlayOpacity; 46 47 v2f vert(appdata v) { 48 v2f o; 49 o.pos = UnityObjectToClipPos(v.vertex); 50 o.grabPos = ComputeGrabScreenPos(o.pos); 51 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 52 return o; 53 } 54 55 half4 frag(v2f i) : SV_Target 56 { 57 half4 color = tex2Dproj(_BackgroundTexture, i.grabPos); 58 half4 textureColor = tex2D(_MainTex, i.uv); 59 half4 overlayColor = tex2D(_OverlayTex, i.uv); 60 61 //テクスチャを合成 62 color.rgb = lerp( color.rgb, textureColor.rgb, textureColor.a * _MainTexOpacity); 63 64 //オーバーレイ 65 overlayColor.rgb = color.rgb < 0.5 ? 2.0 * color.rgb * overlayColor.rgb : 1.0 - 2.0 * (1.0 - color.rgb) * (1.0 - overlayColor.rgb); 66 67 //オーバーレイを重ねた後の画像を合成 68 color.rgb = lerp( color.rgb, overlayColor.rgb, textureColor.a * overlayColor.a * _OverlayOpacity); 69 70 return color; 71 } 72 ENDCG 73 } 74 } 75}
投稿2020/10/09 07:18
編集2020/10/09 07:44総合スコア198
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。