teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

改造版シェーダーを追記

2019/11/08 19:45

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -35,4 +35,156 @@
35
35
  }
36
36
  }
37
37
  }
38
+ ```
39
+
40
+ **追記**
41
+ 外周部が引き延ばされる現象を防止する措置を加えてみました。
42
+ ```ShaderLab
43
+ Shader "Projector/LightClipped" {
44
+ Properties {
45
+ _Color ("Main Color", Color) = (1,1,1,1)
46
+ _ShadowTex ("Cookie", 2D) = "" {}
47
+ _FalloffTex ("FallOff", 2D) = "" {}
48
+ }
49
+
50
+ Subshader {
51
+ Tags {"Queue"="Transparent"}
52
+ Pass {
53
+ ZWrite Off
54
+ ColorMask RGB
55
+ Blend DstColor One
56
+ Offset -1, -1
57
+
58
+ CGPROGRAM
59
+ #pragma vertex vert
60
+ #pragma fragment frag
61
+ #pragma multi_compile_fog
62
+ #include "UnityCG.cginc"
63
+
64
+ struct v2f {
65
+ float4 uvShadow : TEXCOORD0;
66
+ float4 uvFalloff : TEXCOORD1;
67
+ UNITY_FOG_COORDS(2)
68
+ float4 pos : SV_POSITION;
69
+ };
70
+
71
+ float4x4 unity_Projector;
72
+ float4x4 unity_ProjectorClip;
73
+
74
+ v2f vert (float4 vertex : POSITION)
75
+ {
76
+ v2f o;
77
+ o.pos = UnityObjectToClipPos(vertex);
78
+ o.uvShadow = mul (unity_Projector, vertex);
79
+ o.uvFalloff = mul (unity_ProjectorClip, vertex);
80
+ UNITY_TRANSFER_FOG(o,o.pos);
81
+ return o;
82
+ }
83
+
84
+ fixed4 _Color;
85
+ sampler2D _ShadowTex;
86
+ sampler2D _FalloffTex;
87
+
88
+ fixed4 frag (v2f i) : SV_Target
89
+ {
90
+ // まずuvShadowをプロジェクション座標に直し...
91
+ float4 projCoord = UNITY_PROJ_COORD(i.uvShadow);
92
+
93
+ // 元のコードでは同次座標形式のままtex2Dprojでテクスチャサンプリングしているが、
94
+ // 代わりに事前にwで割ってしまい...
95
+ projCoord /= projCoord.w;
96
+
97
+ // 得られたUV座標を0~1にクランプ、さらにクランプ前の座標の絶対値を引くと
98
+ // 結果は座標が0~1の範囲内であれば0、範囲を外れていればマイナスになるはずなので
99
+ // これをclipに渡せば、値がマイナスのフラグメントは破棄される
100
+ clip(clamp(projCoord.xy, 0.0, 1.0) - abs(projCoord.xy));
101
+
102
+ // _ShadowTexからテクスチャサンプリングを行う
103
+ // projCoordはw除算済みなので、tex2Dprojの代わりにtex2Dを使う
104
+ fixed4 texS = tex2D (_ShadowTex, projCoord.xy);
105
+
106
+ texS.rgb *= _Color.rgb;
107
+ texS.a = 1.0-texS.a;
108
+
109
+ fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
110
+ fixed4 res = texS * texF.a;
111
+
112
+ UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(0,0,0,0));
113
+ return res;
114
+ }
115
+ ENDCG
116
+ }
117
+ }
118
+ }
119
+ ```
120
+ もし色合成方法を通常のUnlitシェーダー風にする場合、下記のようにしてみてはどうでしょうか。
121
+ ```ShaderLab
122
+ Shader "Projector/UnlitClipped" {
123
+ Properties {
124
+ _Color ("Main Color", Color) = (1,1,1,1)
125
+ _ShadowTex ("Cookie", 2D) = "white" {}
126
+ _FalloffTex ("FallOff", 2D) = "white" {}
127
+ }
128
+
129
+ Subshader {
130
+ Tags {"Queue"="Transparent"}
131
+ Pass {
132
+ ZWrite Off
133
+
134
+ // 合成方法を一般的なアルファブレンディングに変更
135
+ // カラーマスクも指定せず、アルファチャンネルへも通常通り書き込むようにする
136
+ Blend SrcAlpha OneMinusSrcAlpha
137
+
138
+ Offset -1, -1
139
+
140
+ CGPROGRAM
141
+ #pragma vertex vert
142
+ #pragma fragment frag
143
+ #pragma multi_compile_fog
144
+ #include "UnityCG.cginc"
145
+
146
+ struct v2f {
147
+ float4 uvShadow : TEXCOORD0;
148
+ float4 uvFalloff : TEXCOORD1;
149
+ UNITY_FOG_COORDS(2)
150
+ float4 pos : SV_POSITION;
151
+ };
152
+
153
+ float4x4 unity_Projector;
154
+ float4x4 unity_ProjectorClip;
155
+
156
+ v2f vert (float4 vertex : POSITION)
157
+ {
158
+ v2f o;
159
+ o.pos = UnityObjectToClipPos(vertex);
160
+ o.uvShadow = mul (unity_Projector, vertex);
161
+ o.uvFalloff = mul (unity_ProjectorClip, vertex);
162
+ UNITY_TRANSFER_FOG(o,o.pos);
163
+ return o;
164
+ }
165
+
166
+ fixed4 _Color;
167
+ sampler2D _ShadowTex;
168
+ sampler2D _FalloffTex;
169
+
170
+ fixed4 frag (v2f i) : SV_Target
171
+ {
172
+ // _ShadowTexのサンプリングはLightClippedと同様に行い...
173
+ float4 projCoord = UNITY_PROJ_COORD(i.uvShadow);
174
+ projCoord /= projCoord.w;
175
+ clip(clamp(projCoord.xy, 0.0, 1.0) - abs(projCoord.xy));
176
+ fixed4 texS = tex2D (_ShadowTex, projCoord.xy);
177
+
178
+ // 以降の色合成は通常のUnlitシェーダーと同様に
179
+ // 普通のアルファブレンディングを前提としたスタイルに変える
180
+ texS *= _Color;
181
+ fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
182
+ fixed4 res = texS * fixed4(1.0, 1.0, 1.0, texF.a);
183
+ UNITY_APPLY_FOG(i.fogCoord, res);
184
+ return res;
185
+ }
186
+ ENDCG
187
+ }
188
+ }
189
+ }
38
190
  ```