Skip to content

Commit caa4dfd

Browse files
committed
Add MatCap shading
1 parent 4c73b9c commit caa4dfd

4 files changed

Lines changed: 147 additions & 31 deletions

File tree

‎Inc/Effects.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,14 +879,15 @@ namespace DirectX
879879
};
880880

881881
//------------------------------------------------------------------------------
882-
// Built-in shader for non-photorealistic rendering (cel shading, Gooch shading).
882+
// Built-in shader for non-photorealistic rendering
883883
class NPREffect : public IEffect, public IEffectMatrices, public IEffectLights
884884
{
885885
public:
886886
enum Mode : uint32_t
887887
{
888888
Mode_Cel = 0, // Cel (toon) shading
889889
Mode_Gooch, // Gooch shading
890+
Mode_MatCap, // Material Capture shading
890891
};
891892

892893
DIRECTX_TOOLKIT_API explicit NPREffect(_In_ ID3D11Device* device);
@@ -940,6 +941,9 @@ namespace DirectX
940941
DIRECTX_TOOLKIT_API void XM_CALLCONV SetGoochCoolColor(FXMVECTOR value, float alpha = 0.25f);
941942
DIRECTX_TOOLKIT_API void XM_CALLCONV SetGoochWarmColor(FXMVECTOR value, float beta = 0.25f);
942943

944+
// MatCap shading setting.
945+
DIRECTX_TOOLKIT_API void __cdecl SetMatCap(_In_opt_ ID3D11ShaderResourceView* value);
946+
943947
// Rim lighting settings.
944948
DIRECTX_TOOLKIT_API void XM_CALLCONV SetRimLightingColor(FXMVECTOR value);
945949
DIRECTX_TOOLKIT_API void __cdecl SetRimLightingPower(float power);

‎Src/NPREffect.cpp‎

Lines changed: 97 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ namespace
3939
using ConstantBufferType = NPREffectConstants;
4040

4141
static constexpr int VertexShaderCount = 16;
42-
static constexpr int PixelShaderCount = 4;
43-
static constexpr int ShaderPermutationCount = 32;
42+
static constexpr int PixelShaderCount = 6;
43+
static constexpr int ShaderPermutationCount = 48;
4444

45-
static constexpr int ModeCount = 2;
45+
static constexpr int ModeCount = 3;
4646
};
4747

4848

@@ -74,6 +74,7 @@ class NPREffect::Impl : public EffectBase<NPREffectTraits>
7474
bool textureEnabled;
7575
NPREffect::Mode nprMode;
7676
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> texture;
77+
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> matcap;
7778

7879
int GetCurrentShaderPermutation() const noexcept;
7980

@@ -112,8 +113,12 @@ namespace
112113

113114
#include "XboxOneNPREffect_PSCelShading.inc"
114115
#include "XboxOneNPREffect_PSCelShadingTx.inc"
116+
115117
#include "XboxOneNPREffect_PSGoochShading.inc"
116118
#include "XboxOneNPREffect_PSGoochShadingTx.inc"
119+
120+
#include "XboxOneNPREffect_PSMatCapShading.inc"
121+
#include "XboxOneNPREffect_PSMatCapShadingTx.inc"
117122
#else
118123
#include "NPREffect_VSNPREffect.inc"
119124
#include "NPREffect_VSNPREffectInst.inc"
@@ -144,6 +149,9 @@ namespace
144149

145150
#include "NPREffect_PSGoochShading.inc"
146151
#include "NPREffect_PSGoochShadingTx.inc"
152+
153+
#include "NPREffect_PSMatCapShading.inc"
154+
#include "NPREffect_PSMatCapShadingTx.inc"
147155
#endif
148156
}
149157

@@ -175,61 +183,79 @@ const int EffectBase<NPREffectTraits>::VertexShaderIndices[] =
175183
{
176184
0, // cel shading
177185
0, // gooch shading
186+
0, // matcap shading
178187

179188
1, // vertex color + cel shading
180189
1, // vertex color + gooch shading
190+
1, // vertex color + matcap shading
181191

182192
2, // cel shading (biased vertex normal)
183193
2, // gooch shading (biased vertex normal)
194+
2, // matcap shading (biased vertex normal)
184195

185196
3, // vertex color (biased vertex normal) + cel shading
186197
3, // vertex color (biased vertex normal) + gooch shading
198+
3, // vertex color (biased vertex normal) + matcap shading
187199

188200
4, // instancing + cel shading
189201
4, // instancing + gooch shading
202+
4, // instancing + matcap shading
190203

191204
5, // instancing + vertex color + cel shading
192205
5, // instancing + vertex color + gooch shading
206+
5, // instancing + vertex color + matcap shading
193207

194208
6, // instancing (biased vertex normal) + cel shading
195209
6, // instancing (biased vertex normal) + gooch shading
210+
6, // instancing (biased vertex normal) + matcap shading
196211

197212
7, // instancing + vertex color (biased vertex normal) + cel shading
198213
7, // instancing + vertex color (biased vertex normal) + gooch shading
214+
7, // instancing + vertex color (biased vertex normal) + matcap shading
199215

200216
8, // cel shading + texture
201217
8, // gooch shading + texture
218+
8, // matcap shading + texture
202219

203220
9, // vertex color + cel shading + texture
204221
9, // vertex color + gooch shading + texture
222+
9, // vertex color + matcap shading + texture
205223

206224
10, // cel shading (biased vertex normal) + texture
207225
10, // gooch shading (biased vertex normal) + texture
226+
10, // matcap shading (biased vertex normal) + texture
208227

209228
11, // vertex color (biased vertex normal) + cel shading + texture
210229
11, // vertex color (biased vertex normal) + gooch shading + texture
230+
11, // vertex color (biased vertex normal) + matcap shading + texture
211231

212232
12, // instancing + cel shading + texture
213233
12, // instancing + gooch shading + texture
234+
12, // instancing + matcap shading + texture
214235

215236
13, // instancing + vertex color + cel shading + texture
216237
13, // instancing + vertex color + gooch shading + texture
238+
13, // instancing + vertex color + matcap shading + texture
217239

218240
14, // instancing (biased vertex normal) + cel shading + texture
219241
14, // instancing (biased vertex normal) + gooch shading + texture
242+
14, // instancing (biased vertex normal) + matcap shading + texture
220243

221244
15, // instancing + vertex color (biased vertex normal) + cel shading + texture
222245
15, // instancing + vertex color (biased vertex normal) + gooch shading + texture
246+
15, // instancing + vertex color (biased vertex normal) + matcap shading + texture
223247
};
224248

225249

226250
template<>
227251
const ShaderBytecode EffectBase<NPREffectTraits>::PixelShaderBytecode[] =
228252
{
229-
{ NPREffect_PSCelShading, sizeof(NPREffect_PSCelShading) },
230-
{ NPREffect_PSGoochShading, sizeof(NPREffect_PSGoochShading) },
231-
{ NPREffect_PSCelShadingTx, sizeof(NPREffect_PSCelShadingTx) },
232-
{ NPREffect_PSGoochShadingTx, sizeof(NPREffect_PSGoochShadingTx) },
253+
{ NPREffect_PSCelShading, sizeof(NPREffect_PSCelShading) },
254+
{ NPREffect_PSGoochShading, sizeof(NPREffect_PSGoochShading) },
255+
{ NPREffect_PSMatCapShading, sizeof(NPREffect_PSMatCapShading) },
256+
{ NPREffect_PSCelShadingTx, sizeof(NPREffect_PSCelShadingTx) },
257+
{ NPREffect_PSGoochShadingTx, sizeof(NPREffect_PSGoochShadingTx) },
258+
{ NPREffect_PSMatCapShadingTx, sizeof(NPREffect_PSMatCapShadingTx) },
233259
};
234260

235261

@@ -238,51 +264,67 @@ const int EffectBase<NPREffectTraits>::PixelShaderIndices[] =
238264
{
239265
0, // cel shading
240266
1, // gooch shading
267+
2, // matcap shading
241268

242269
0, // vertex color + cel shading
243270
1, // vertex color + gooch shading
271+
2, // vertex color + matcap shading
244272

245273
0, // cel shading (biased vertex normal)
246274
1, // gooch shading (biased vertex normal)
275+
2, // matcap shading (biased vertex normal)
247276

248277
0, // vertex color (biased vertex normal) + cel shading
249278
1, // vertex color (biased vertex normal) + gooch shading
279+
2, // vertex color (biased vertex normal) + matcap shading
250280

251281
0, // instancing + cel shading
252282
1, // instancing + gooch shading
283+
2, // instancing + matcap shading
253284

254285
0, // instancing + vertex color + cel shading
255286
1, // instancing + vertex color + gooch shading
287+
2, // instancing + vertex color + matcap shading
256288

257289
0, // instancing (biased vertex normal) + cel shading
258290
1, // instancing (biased vertex normal) + gooch shading
291+
2, // instancing (biased vertex normal) + matcap shading
259292

260293
0, // instancing + vertex color (biased vertex normal) + cel shading
261294
1, // instancing + vertex color (biased vertex normal) + gooch shading
295+
2, // instancing + vertex color (biased vertex normal) + matcap shading
262296

263-
2, // cel shading + texture
264-
3, // gooch shading + texture
297+
3, // cel shading + texture
298+
4, // gooch shading + texture
299+
5, // matcap shading + texture
265300

266-
2, // vertex color + cel shading + texture
267-
3, // vertex color + gooch shading + texture
301+
3, // vertex color + cel shading + texture
302+
4, // vertex color + gooch shading + texture
303+
5, // vertex color + matcap shading + texture
268304

269-
2, // cel shading (biased vertex normal) + texture
270-
3, // gooch shading (biased vertex normal) + texture
305+
3, // cel shading (biased vertex normal) + texture
306+
4, // gooch shading (biased vertex normal) + texture
307+
5, // matcap shading (biased vertex normal) + texture
271308

272-
2, // vertex color (biased vertex normal) + cel shading + texture
273-
3, // vertex color (biased vertex normal) + gooch shading + texture
309+
3, // vertex color (biased vertex normal) + cel shading + texture
310+
4, // vertex color (biased vertex normal) + gooch shading + texture
311+
5, // vertex color (biased vertex normal) + matcap shading + texture
274312

275-
2, // instancing + cel shading + texture
276-
3, // instancing + gooch shading + texture
313+
3, // instancing + cel shading + texture
314+
4, // instancing + gooch shading + texture
315+
5, // instancing + matcap shading + texture
277316

278-
2, // instancing + vertex color + cel shading + texture
279-
3, // instancing + vertex color + gooch shading + texture
317+
3, // instancing + vertex color + cel shading + texture
318+
4, // instancing + vertex color + gooch shading + texture
319+
5, // instancing + vertex color + matcap shading + texture
280320

281-
2, // instancing (biased vertex normal) + cel shading + texture
282-
3, // instancing (biased vertex normal) + gooch shading + texture
321+
3, // instancing (biased vertex normal) + cel shading + texture
322+
4, // instancing (biased vertex normal) + gooch shading + texture
323+
5, // instancing (biased vertex normal) + matcap shading + texture
283324

284-
2, // instancing + vertex color (biased vertex normal) + cel shading + texture
285-
3, // instancing + vertex color (biased vertex normal) + gooch shading + texture
325+
3, // instancing + vertex color (biased vertex normal) + cel shading + texture
326+
4, // instancing + vertex color (biased vertex normal) + gooch shading + texture
327+
5, // instancing + vertex color (biased vertex normal) + matcap shading + texture
286328
};
287329
#pragma endregion
288330

@@ -323,25 +365,25 @@ int NPREffect::Impl::GetCurrentShaderPermutation() const noexcept
323365
// Support vertex coloring?
324366
if (vertexColorEnabled)
325367
{
326-
permutation += 2;
368+
permutation += 3;
327369
}
328370

329371
if (biasedVertexNormals)
330372
{
331373
// Compressed normals need to be scaled and biased in the vertex shader.
332-
permutation += 4;
374+
permutation += 6;
333375
}
334376

335377
if (instancing)
336378
{
337379
// Vertex shader needs to use vertex matrix transform.
338-
permutation += 8;
380+
permutation += 12;
339381
}
340382

341383
// Use shaders without texture coordinates?
342384
if (textureEnabled)
343385
{
344-
permutation += 16;
386+
permutation += 24;
345387
}
346388

347389
return permutation;
@@ -385,10 +427,28 @@ void NPREffect::Impl::Apply(_In_ ID3D11DeviceContext* deviceContext)
385427
ApplyShaders(deviceContext, GetCurrentShaderPermutation());
386428

387429
// Set texture.
388-
if (textureEnabled)
430+
switch (nprMode)
389431
{
390-
ID3D11ShaderResourceView* srv = texture.Get();
391-
deviceContext->PSSetShaderResources(0, 1, &srv);
432+
case Mode_MatCap:
433+
if (textureEnabled)
434+
{
435+
ID3D11ShaderResourceView* srvs[] = { texture.Get(), matcap.Get() };
436+
deviceContext->PSSetShaderResources(0, 2, srvs);
437+
}
438+
else
439+
{
440+
ID3D11ShaderResourceView* srv = matcap.Get();
441+
deviceContext->PSSetShaderResources(0, 1, &srv);
442+
}
443+
break;
444+
445+
default:
446+
if (textureEnabled)
447+
{
448+
ID3D11ShaderResourceView* srv = texture.Get();
449+
deviceContext->PSSetShaderResources(0, 1, &srv);
450+
}
451+
break;
392452
}
393453
}
394454

@@ -637,6 +697,13 @@ void NPREffect::SetGoochWarmColor(FXMVECTOR value, float beta)
637697
}
638698

639699

700+
// MatCap shading setting.
701+
void NPREffect::SetMatCap(_In_opt_ ID3D11ShaderResourceView* value)
702+
{
703+
pImpl->matcap = value;
704+
}
705+
706+
640707
// Rim lighting settings.
641708
void NPREffect::SetRimLightingColor(FXMVECTOR value)
642709
{

‎Src/Shaders/CompileShaders.cmd‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ call :CompileShader%1 NPREffect ps PSCelShadingTx
252252
call :CompileShader%1 NPREffect ps PSGoochShading
253253
call :CompileShader%1 NPREffect ps PSGoochShadingTx
254254

255+
call :CompileShader%1 NPREffect ps PSMatCapShading
256+
call :CompileShader%1 NPREffect ps PSMatCapShadingTx
257+
255258
call :CompileShader%1 SpriteEffect vs SpriteVertexShader
256259
call :CompileShader%1 SpriteEffect ps SpritePixelShader
257260

‎Src/Shaders/NPREffect.fx‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
Texture2D<float4> Texture : register(t0);
8+
Texture2D<float4> Texture2 : register(t1);
89
SamplerState Sampler : register(s0);
910

1011

@@ -375,3 +376,44 @@ float4 PSGoochShadingTx(PSInputPixelLightingTx pin) : SV_Target0
375376

376377
return float4(color, pin.Diffuse.a * texColor.a);
377378
}
379+
380+
381+
//--- MatCap shading ---
382+
383+
// Pixel shader: MatCap shading.
384+
float4 PSMatCapShading(PSInputPixelLighting pin) : SV_Target0
385+
{
386+
float3 normal = normalize(pin.NormalWS);
387+
float3 viewDir = normalize(EyePosition - pin.PositionWS.xyz);
388+
float3 reflectDir = reflect(viewDir, normal);
389+
390+
float2 uv = reflectDir.xy * 0.5 + 0.5;
391+
392+
// Sample matcap texture
393+
float4 matcap = Texture.Sample(Sampler, uv);
394+
395+
float3 color = pin.Diffuse.rgb * matcap.rgb;
396+
397+
return float4(color, pin.Diffuse.a);
398+
}
399+
400+
401+
// Pixel shader: MatCap shading + texture.
402+
float4 PSMatCapShadingTx(PSInputPixelLightingTx pin) : SV_Target0
403+
{
404+
float3 normal = normalize(pin.NormalWS);
405+
float3 viewDir = normalize(EyePosition - pin.PositionWS.xyz);
406+
float3 reflectDir = reflect(viewDir, normal);
407+
408+
float2 uv = reflectDir.xy * 0.5 + 0.5;
409+
410+
// Sample base texture
411+
float4 texColor = Texture.Sample(Sampler, pin.TexCoord);
412+
413+
// Sample matcap texture
414+
float4 matcap = Texture2.Sample(Sampler, uv);
415+
416+
float3 color = pin.Diffuse.rgb * texColor.rgb * matcap.rgb;
417+
418+
return float4(color, pin.Diffuse.a * texColor.a);
419+
}

0 commit comments

Comments
 (0)