回答編集履歴

1

マテリアル案を追記

2021/01/21 03:47

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -5,3 +5,229 @@
5
5
  アルファが0のときに完全透明にしたいとなると、ブレンドモードを`Blend SrcAlpha OneMinusSrcAlpha`にするのがいいかと思います。ですがそれだと普通のアルファブレンディングと同じになってしまうはずですが、ご質問者さんの意図する挙動はどのようなものでしょうか。
6
6
 
7
7
  「アルファ1だと完全不透明、アルファを下げていくとだんだん加算合成のようになっていき、さらにアルファを下げていくと絵が薄くなり、アルファ0で完全透明」みたいな感じでしょうか?
8
+
9
+
10
+
11
+ ##マテリアル案
12
+
13
+
14
+
15
+ 一案として下記のようなものはいかがでしょうか?
16
+
17
+
18
+
19
+ ```ShaderLab
20
+
21
+ // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
22
+
23
+
24
+
25
+ Shader "Sprites/TestShader"
26
+
27
+ {
28
+
29
+ Properties
30
+
31
+ {
32
+
33
+ [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
34
+
35
+ _Color ("Tint", Color) = (1,1,1,1)
36
+
37
+ [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
38
+
39
+ [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
40
+
41
+ [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
42
+
43
+ [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
44
+
45
+ [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
46
+
47
+ _Alpha ("Alpha", Range(0, 1)) = 1
48
+
49
+ _Exponent ("Exponent", Range(1, 16)) = 1
50
+
51
+ }
52
+
53
+
54
+
55
+ SubShader
56
+
57
+ {
58
+
59
+ Tags
60
+
61
+ {
62
+
63
+ "Queue"="Transparent"
64
+
65
+ "IgnoreProjector"="True"
66
+
67
+ "RenderType"="Transparent"
68
+
69
+ "PreviewType"="Plane"
70
+
71
+ "CanUseSpriteAtlas"="True"
72
+
73
+ }
74
+
75
+
76
+
77
+ Cull Off
78
+
79
+ Lighting Off
80
+
81
+ ZWrite Off
82
+
83
+ Blend One OneMinusSrcAlpha
84
+
85
+
86
+
87
+ Pass
88
+
89
+ {
90
+
91
+ CGPROGRAM
92
+
93
+ #pragma vertex vert
94
+
95
+ #pragma fragment frag
96
+
97
+ #pragma target 2.0
98
+
99
+ #pragma multi_compile_instancing
100
+
101
+ #pragma multi_compile _ PIXELSNAP_ON
102
+
103
+ #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
104
+
105
+ #include "UnitySprites.cginc"
106
+
107
+
108
+
109
+ struct v2fCustom
110
+
111
+ {
112
+
113
+ float4 vertex : SV_POSITION;
114
+
115
+ fixed4 color : COLOR;
116
+
117
+ float2 texcoord : TEXCOORD0;
118
+
119
+ float2 position : TEXCOORD1;
120
+
121
+ UNITY_VERTEX_OUTPUT_STEREO
122
+
123
+ };
124
+
125
+
126
+
127
+ v2fCustom vert(appdata_t IN)
128
+
129
+ {
130
+
131
+ v2fCustom OUT;
132
+
133
+
134
+
135
+ UNITY_SETUP_INSTANCE_ID (IN);
136
+
137
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
138
+
139
+
140
+
141
+ OUT.vertex = UnityFlipSprite(IN.vertex, _Flip);
142
+
143
+ OUT.vertex = UnityObjectToClipPos(OUT.vertex);
144
+
145
+ OUT.texcoord = IN.texcoord;
146
+
147
+ OUT.color = IN.color * _Color * _RendererColor;
148
+
149
+ OUT.position = IN.vertex.xy * 2;
150
+
151
+
152
+
153
+ #ifdef PIXELSNAP_ON
154
+
155
+ OUT.vertex = UnityPixelSnap (OUT.vertex);
156
+
157
+ #endif
158
+
159
+
160
+
161
+ return OUT;
162
+
163
+ }
164
+
165
+
166
+
167
+ float _Alpha;
168
+
169
+ float _Exponent;
170
+
171
+
172
+
173
+ fixed4 frag(v2fCustom IN) : SV_Target
174
+
175
+ {
176
+
177
+ fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
178
+
179
+
180
+
181
+ // アルファ変化時の見た目の変化を実演するため、アルファを
182
+
183
+ // プロパティにして外部から操作できるようにした
184
+
185
+ float alpha = _Alpha;
186
+
187
+ c.a = alpha;
188
+
189
+
190
+
191
+ // 通常のアルファブレンディングではRGBにアルファがそのまま乗算されるが、
192
+
193
+ // ここで「白黒反転して冪乗して白黒反転」の操作を加えることで
194
+
195
+ // 乗算値の変化が非線形なカーブとなって、中間のアルファのときに
196
+
197
+ // 乗算値が通常よりも高くなり、加算合成に近づく
198
+
199
+ c.rgb *= 1.0 - pow(1.0 - c.a, _Exponent);
200
+
201
+
202
+
203
+ return c;
204
+
205
+ }
206
+
207
+ ENDCG
208
+
209
+ }
210
+
211
+ }
212
+
213
+ }
214
+
215
+ ```
216
+
217
+
218
+
219
+ ブレンドモードは`Blend One OneMinusSrcAlpha`としておき、RGBへのアルファ乗算は`frag`内で行うようにしてみました。
220
+
221
+ Exponentが1のとき...つまり通常のアルファブレンディングだと下図のようになりますが(さまざまなアルファ値のときにどう見えるかをご覧に入れようと思ってGIFにしたのですが、代償として階調数が落ちてしまいました)...
222
+
223
+
224
+
225
+ ![図1](0e8a20b69f38fb6b1bc688f14a2d442b.gif)
226
+
227
+
228
+
229
+ Exponentを8に上げると、半透明のときにRGBに乗算される値が実際のアルファよりも高めに引き上げられ、加算合成に近い結果になります。ですがアルファが0になると乗算値も0まで落ち込むので、アルファが0のときには完全透明になるというわけです。
230
+
231
+
232
+
233
+ ![図2](404b2c52d93d8ce1c7e9faa3c5d01f8d.gif)