-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathShadekai.fxsub
347 lines (282 loc) · 10.7 KB
/
Shadekai.fxsub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Shadekai (Project Sekai shader for MMD) v1.3
//
// By: KH40
// Base shader: 舞力介入P
// Special thanks: Yukikami
//
////////////////////////////////////////////////////////////////////////////////////////////////
#include "HgShadow_ObjHeader.fxh"
// 座法変換行列
float4x4 WorldViewProjMatrix : WORLDVIEWPROJECTION;
float4x4 WorldMatrix : WORLD;
float4x4 LightWorldViewProjMatrix : WORLDVIEWPROJECTION < string Object = "Light"; >;
float3 LightDirection : DIRECTION < string Object = "Light"; >;
float3 CameraPosition : POSITION < string Object = "Camera"; >;
// マテリアル色
float4 MaterialDiffuse : DIFFUSE < string Object = "Geometry"; >;
float3 MaterialAmbient : AMBIENT < string Object = "Geometry"; >;
float3 MaterialEmmisive : EMISSIVE < string Object = "Geometry"; >;
float3 MaterialSpecular : SPECULAR < string Object = "Geometry"; >;
float SpecularPower : SPECULARPOWER < string Object = "Geometry"; >;
float3 MaterialToon : TOONCOLOR;
// ライト色
float3 LightDiffuse : DIFFUSE < string Object = "Light"; >;
float3 LightAmbient : AMBIENT < string Object = "Light"; >;
float3 LightSpecular : SPECULAR < string Object = "Light"; >;
static float4 DiffuseColor = MaterialDiffuse * float4(LightDiffuse, 1.0f);
static float3 AmbientColor = MaterialAmbient * LightAmbient + MaterialEmmisive;
static float3 SpecularColor = MaterialSpecular * LightSpecular;
bool use_texture; //テクスチャの有無
bool parthf; // パースペクティブフラグ
bool transp; // 半透明フラグ
// オブジェクトのテクスチャ
texture ObjectTexture: MATERIALTEXTURE;
sampler ObjTexSampler = sampler_state
{
texture = <ObjectTexture>;
MINFILTER = ANISOTROPIC;
MAGFILTER = ANISOTROPIC;
MIPFILTER = ANISOTROPIC;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
MAXANISOTROPY = 16;
};
texture2D SekaiMap <
string ResourceName = SekaiMap_Texture;
int MipLevels = 0;
>;
sampler2D SekaiMapSamp = sampler_state {
texture = <SekaiMap>;
MINFILTER = ANISOTROPIC;
MAGFILTER = ANISOTROPIC;
MIPFILTER = ANISOTROPIC;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
MAXANISOTROPY = 16;
};
texture2D ShadowColorMap <
string ResourceName = ShadowColorMap_Texture;
int MipLevels = 0;
>;
sampler2D ShadowColorMapSamp = sampler_state {
texture = <ShadowColorMap>;
MINFILTER = ANISOTROPIC;
MAGFILTER = ANISOTROPIC;
MIPFILTER = ANISOTROPIC;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
MAXANISOTROPY = 16;
};
#if Self_LightDirection == 1
float4x4 Self_Lighting_Matrix_Toon : CONTROLOBJECT < string name = Self_Lighting_Model ; string item = Self_Lighting_Bone_Toon ; >;
static float3 Self_Lighting_Dir_Toon = normalize(Self_Lighting_Matrix_Toon._31_32_33);
float4x4 Self_Lighting_Matrix_Rim : CONTROLOBJECT < string name = Self_Lighting_Model ; string item = Self_Lighting_Bone_Rim ; >;
static float3 Self_Lighting_Dir_Rim = normalize(Self_Lighting_Matrix_Rim._31_32_33);
#endif
float Color_Burn(float base, float blend)
{
if (base >= 1.0)
return 1.0;
else if (blend <= 0.0)
return 0.0;
else
return 1.0 - min(1.0, (1.0-base) / blend);
}
float3 Color_Burn(float3 base, float3 blend)
{
return float3( Color_Burn(base.r, blend.r),
Color_Burn(base.g, blend.g),
Color_Burn(base.b, blend.b) );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// シャドウバッファのサンプラ。"register(s0)"なのはMMDがs0を使っているから
sampler DefSampler : register(s0);
struct BufferShadow_OUTPUT
{
float4 Pos : POSITION; // 射影変換座標
float2 Tex : TEXCOORD1; // テクスチャ
float3 Normal : TEXCOORD2; // 法線
float3 Eye : TEXCOORD3; // カメラとの相対位置
float4 VColor : TEXCOORD4;
float4 PPos : TEXCOORD5; // 射影座標
float4 Color : COLOR0; // ディフューズ色
};
// 頂点シェーダ
BufferShadow_OUTPUT Basic_VS(float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0, float4 VColor : TEXCOORD2)
{
BufferShadow_OUTPUT Out = (BufferShadow_OUTPUT)0;
// カメラ視点のワールドビュー射影変換
Out.Pos = mul( Pos, WorldViewProjMatrix );
Out.PPos = Out.Pos;
// カメラとの相対位置
Out.Eye = CameraPosition - mul( Pos, WorldMatrix );
// 頂点法線
Out.Normal = normalize( mul( Normal, (float3x3)WorldMatrix ) );
// ディフューズ色+アンビエント色 計算
#if Self_LightDirection == 1
LightDirection = Self_Lighting_Dir_Toon;
#endif
Out.Color.rgb = saturate( max(0,dot( Out.Normal, -LightDirection )) * DiffuseColor.rgb + AmbientColor );
Out.Color.a = DiffuseColor.a;
// テクスチャ座標
Out.Tex = Tex;
Out.VColor = VColor;
return Out;
}
// ピクセルシェーダ
float4 Basic_PS( BufferShadow_OUTPUT IN, uniform bool Z_Enable ) : COLOR
{
#if Front_Object == 1
if(!Z_Enable)
{
if(IN.VColor.b == 0) {discard;}
}
else
{
if(IN.VColor.b == 1) {discard;}
}
#endif
#if Self_LightDirection == 1
LightDirection = Self_Lighting_Dir_Toon;
#endif
float3 Shadow_Color = float3(0,0,0);
float3 Rim_Color = float3(0,0,0);
float3 Ambient_Color = float3(1,1,1);
float Ambient_Sensitivity = 0.75;
float Ambient_Dark = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////
if (Controller)
{
Rim_Intensity = Rim_Intensity_F;
Rim_Length = Rim_Length_F;
Rim_Thickness = Rim_Thickness_F;
Rim_Color = float3(Rim_Color_R_F,Rim_Color_G_F,Rim_Color_B_F);
Ambient_Color.r += (Ambient_Color_R_F) + (-Ambient_Color_G_F) + (-Ambient_Color_B_F);
Ambient_Color.g += (-Ambient_Color_R_F) + (Ambient_Color_G_F) + (-Ambient_Color_B_F);
Ambient_Color.b += (-Ambient_Color_R_F) + (-Ambient_Color_G_F) + (Ambient_Color_B_F);
Ambient_Color.rgb = lerp(1,saturate(Ambient_Color.rgb),Ambient_Sensitivity);
Ambient_Dark = Ambient_Dark_F;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
float4 GlobalLight = IN.Color;
float4 TexColor = tex2D( ObjTexSampler, IN.Tex );
float4 ShadowTexColor = tex2D( ShadowColorMapSamp, IN.Tex );
float4 Color;
float comp = ((saturate(dot(IN.Normal,-LightDirection))));
comp = smoothstep(0,0.01,comp);
#if Shadow == 1
if(HgShadow_Valid)
{
float compshadow = HgShadow_GetSelfShadowRate(IN.PPos);
#if Shadow_Sharp == 1
compshadow = step(0.25,compshadow);
#endif
comp = min(comp,compshadow);
}
#endif
Color = lerp(ShadowTexColor, TexColor, comp);
float3 ColorSkin = Color.rgb * Skin_Color[Character]/255;
ColorSkin = max(ColorSkin, SkinShade_Color[Character]/255);
Color.rgb = lerp(Color.rgb,ColorSkin,tex2D(SekaiMapSamp,IN.Tex).r);
Color.rgb *= GlobalLight;
Color.rgb = Color_Burn(Color.rgb,Ambient_Color);
Color.rgb *= (1-Ambient_Dark);
float rim_direction;
#if Self_LightDirection == 1
rim_direction = pow(saturate(dot(IN.Normal,-Self_Lighting_Dir_Rim)),Rim_Length);
#else
rim_direction = pow(saturate(dot(IN.Normal,-LightDirection)),Rim_Length);
#endif
float rim = 1.0 - saturate(dot(normalize(IN.Eye), IN.Normal));
rim = rim * rim_direction;
rim = smoothstep(Rim_Thickness-0.01,Rim_Thickness+0.01,rim);
if (Controller)
{
Color.rgb += rim * Rim_Color * Rim_Intensity * IN.VColor.g;
}
else
{
Color.rgb += rim * Rim_Intensity * IN.VColor.g;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
if (Controller)
{
Color.rgb = lerp(Color.rgb , float3(IN.VColor.rrr) , EdgeScale_view );
Color.rgb = lerp(Color.rgb , float3(IN.VColor.ggg) , RimScale_view );
Color.rgb = lerp(Color.rgb , float3(IN.VColor.bbb) , FrontObject_view );
Color.rgb = lerp(Color.rgb , tex2D(SekaiMapSamp,IN.Tex).rrr , SkinArea_view );
Color.rgb = lerp(Color.rgb , tex2D(SekaiMapSamp,IN.Tex).ggg , GlowArea_view );
Color.rgb = lerp(Color.rgb , Ambient_Color*(1-Ambient_Dark) , Ambient_view );
}
/////////////////////////////////////////////////////////////////////////////////////////////////
return Color;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct EdgeVS_OUTPUT {
float4 Pos : POSITION; // 射影変換座標
float2 Tex : TEXCOORD1; // テクスチャ
float3 Normal : TEXCOORD2;
};
EdgeVS_OUTPUT Edge_VS(float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0, float4 VColor : TEXCOORD2)
{
EdgeVS_OUTPUT Out = (EdgeVS_OUTPUT)0;
/////////////////////////////////////////////////////////////////////////////////////////////////
if (Controller)
{
Edge_Thickness = Edge_Thickness_F;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// カメラ視点のワールドビュー射影変換
Out.Tex = Tex;
Out.Normal = normalize( mul( Normal, (float3x3)WorldMatrix ) );
Pos.xyz += Normal * Edge_Thickness * VColor.r;
Out.Pos = mul( Pos, WorldViewProjMatrix );
return Out;
}
float4 Edge_PS(EdgeVS_OUTPUT IN) : COLOR
{
float3 EdgeColor = tex2D(ObjTexSampler,IN.Tex).rgb*0.325;
float EdgeAlpha = tex2D(ObjTexSampler,IN.Tex).a;
return float4(EdgeColor,EdgeAlpha);
}
///////////////////////////////////////////////////////////////////////////////////////////////
technique Shadekai_NoShadow < string MMDPass = "object"; > {
pass DrawObject {
VertexShader = compile vs_3_0 Basic_VS();
PixelShader = compile ps_3_0 Basic_PS(true);
}
pass DrawEdge {
CullMode = CW;
VertexShader = compile vs_3_0 Edge_VS();
PixelShader = compile ps_3_0 Edge_PS();
}
#if Front_Object == 1
pass DrawObject_NoZ {
ZEnable = false;
VertexShader = compile vs_3_0 Basic_VS();
PixelShader = compile ps_3_0 Basic_PS(false);
}
#endif
}
// オブジェクト描画用テクニック
technique Shadekai_Shadow < string MMDPass = "object_ss"; > {
pass DrawObject {
VertexShader = compile vs_3_0 Basic_VS();
PixelShader = compile ps_3_0 Basic_PS(true);
}
pass DrawEdge {
CullMode = CW;
VertexShader = compile vs_3_0 Edge_VS();
PixelShader = compile ps_3_0 Edge_PS();
}
#if Front_Object == 1
pass DrawObject_NoZ {
ZEnable = false;
VertexShader = compile vs_3_0 Basic_VS();
PixelShader = compile ps_3_0 Basic_PS(false);
}
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////