1
1
#version 450
2
2
#extension GL_ARB_separate_shader_objects : enable
3
- #pragma import_defines (VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, SHADOWMAP_DEBUG)
3
+ #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_DETAIL_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, VSG_SHADOWS_PCSS, VSG_SHADOWS_SOFT, VSG_SHADOWS_HARD, SHADOWMAP_DEBUG, VSG_ALPHA_TEST)
4
+
5
+ // define by default for backwards compatibility
6
+ #define VSG_SHADOWS_HARD
4
7
5
8
#define VIEW_DESCRIPTOR_SET 1
6
9
#define MATERIAL_DESCRIPTOR_SET 2
@@ -16,8 +19,8 @@ const float c_MinRoughness = 0.04;
16
19
layout (set = MATERIAL_DESCRIPTOR_SET, binding = 0 ) uniform sampler2D diffuseMap;
17
20
#endif
18
21
19
- #ifdef VSG_METALLROUGHNESS_MAP
20
- layout (set = MATERIAL_DESCRIPTOR_SET, binding = 1 ) uniform sampler2D mrMap ;
22
+ #ifdef VSG_DETAIL_MAP
23
+ layout (set = MATERIAL_DESCRIPTOR_SET, binding = 1 ) uniform sampler2D detailMap ;
21
24
#endif
22
25
23
26
#ifdef VSG_NORMAL_MAP
@@ -36,6 +39,10 @@ layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap
36
39
layout (set = MATERIAL_DESCRIPTOR_SET, binding = 5 ) uniform sampler2D specularMap;
37
40
#endif
38
41
42
+ #ifdef VSG_METALLROUGHNESS_MAP
43
+ layout (set = MATERIAL_DESCRIPTOR_SET, binding = 6 ) uniform sampler2D mrMap;
44
+ #endif
45
+
39
46
layout (set = MATERIAL_DESCRIPTOR_SET, binding = 10 ) uniform PbrData
40
47
{
41
48
vec4 baseColorFactor;
@@ -49,13 +56,12 @@ layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData
49
56
} pbr;
50
57
51
58
// ViewDependentState
59
+ layout (constant_id = 3 ) const int lightDataSize = 256 ;
52
60
layout (set = VIEW_DESCRIPTOR_SET, binding = 0 ) uniform LightData
53
61
{
54
- vec4 values[2048 ];
62
+ vec4 values[lightDataSize ];
55
63
} lightData;
56
64
57
- layout (set = VIEW_DESCRIPTOR_SET, binding = 2 ) uniform sampler2DArrayShadow shadowMaps;
58
-
59
65
// Custom state
60
66
layout (set = CUSTOM_DESCRIPTOR_SET, binding = 0 ) uniform Fog
61
67
{
@@ -69,7 +75,9 @@ layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform Fog
69
75
layout (location = 0 ) in vec3 eyePos;
70
76
layout (location = 1 ) in vec3 normalDir;
71
77
layout (location = 2 ) in vec4 vertexColor;
78
+ #ifndef VSG_POINT_SPRITE
72
79
layout (location = 3 ) in vec2 texCoord0;
80
+ #endif
73
81
layout (location = 5 ) in vec3 viewDir;
74
82
75
83
layout (location = 0 ) out vec4 outColor;
@@ -95,19 +103,6 @@ struct PBRInfo
95
103
vec3 specularColor; // color contribution from specular lighting
96
104
};
97
105
98
-
99
- vec4 SRGBtoLINEAR(vec4 srgbIn)
100
- {
101
- vec3 linOut = pow (srgbIn.xyz, vec3 (2.2 ));
102
- return vec4 (linOut,srgbIn.w);
103
- }
104
-
105
- vec4 LINEARtoSRGB(vec4 srgbIn)
106
- {
107
- vec3 linOut = pow (srgbIn.xyz, vec3 (1.0 / 2.2 ));
108
- return vec4 (linOut, srgbIn.w);
109
- }
110
-
111
106
float rcp(const in float value)
112
107
{
113
108
return 1.0 / value;
@@ -118,6 +113,9 @@ float pow5(const in float value)
118
113
return value * value * value * value * value;
119
114
}
120
115
116
+ // include the calculateShadowCoverageForDirectionalLight(..) implementation
117
+ #include "shadows.glsl"
118
+
121
119
// Find the normal for this fragment, pulling either from a predefined normal map
122
120
// or from the interpolated mesh normal and tangent attributes.
123
121
vec3 getNormal()
@@ -291,7 +289,7 @@ vec3 BRDF(vec3 u_LightColor, vec3 v, vec3 n, vec3 l, vec3 h, float perceptualRou
291
289
color *= ao;
292
290
293
291
#ifdef VSG_EMISSIVE_MAP
294
- vec3 emissive = SRGBtoLINEAR( texture(emissiveMap, texCoord0) ).rgb * pbr.emissiveFactor.rgb;
292
+ vec3 emissive = texture(emissiveMap, texCoord0).rgb * pbr.emissiveFactor.rgb;
295
293
#else
296
294
vec3 emissive = pbr.emissiveFactor.rgb;
297
295
#endif
@@ -321,6 +319,10 @@ void main()
321
319
{
322
320
float brightnessCutoff = 0.001 ;
323
321
322
+ #ifdef VSG_POINT_SPRITE
323
+ vec2 texCoord0 = gl_PointCoord .xy;
324
+ #endif
325
+
324
326
float perceptualRoughness = 0.0 ;
325
327
float metallic;
326
328
vec3 diffuseColor;
@@ -335,28 +337,33 @@ void main()
335
337
float v = texture(diffuseMap, texCoord0.st).s * pbr.baseColorFactor;
336
338
baseColor = vertexColor * vec4 (v, v, v, 1.0 );
337
339
#else
338
- baseColor = vertexColor * SRGBtoLINEAR( texture(diffuseMap, texCoord0) ) * pbr.baseColorFactor;
340
+ baseColor = vertexColor * texture(diffuseMap, texCoord0) * pbr.baseColorFactor;
339
341
#endif
340
342
#else
341
343
baseColor = vertexColor * pbr.baseColorFactor;
342
344
#endif
343
345
344
- if (pbr.alphaMask == 1 .0f)
345
- {
346
- if (baseColor.a < pbr.alphaMaskCutoff)
347
- discard ;
348
- }
346
+
347
+ #ifdef VSG_DETAIL_MAP
348
+ vec4 detailColor = texture(detailMap, texCoord0.st);
349
+ baseColor.rgb = mix (baseColor.rgb, detailColor.rgb, detailColor.a);
350
+ #endif
351
+
352
+
353
+ #ifdef VSG_ALPHA_TEST
354
+ if (pbr.alphaMask == 1 .0f && baseColor.a < pbr.alphaMaskCutoff) discard ;
355
+ #endif
349
356
350
357
#ifdef VSG_WORKFLOW_SPECGLOSS
351
358
#ifdef VSG_DIFFUSE_MAP
352
- vec4 diffuse = SRGBtoLINEAR( texture(diffuseMap, texCoord0) );
359
+ vec4 diffuse = texture(diffuseMap, texCoord0);
353
360
#else
354
361
vec4 diffuse = vec4 (1.0 );
355
362
#endif
356
363
357
364
#ifdef VSG_SPECULAR_MAP
358
365
vec4 specular_texel = texture(specularMap, texCoord0);
359
- vec3 specular = SRGBtoLINEAR( specular_texel) .rgb;
366
+ vec3 specular = specular_texel.rgb;
360
367
perceptualRoughness = 1.0 - specular_texel.a;
361
368
#else
362
369
vec3 specular = vec3 (0.0 );
@@ -415,14 +422,14 @@ void main()
415
422
int numDirectionalLights = int (lightNums[1 ]);
416
423
int numPointLights = int (lightNums[2 ]);
417
424
int numSpotLights = int (lightNums[3 ]);
418
- int index = 1 ;
425
+ int lightDataIndex = 1 ;
419
426
420
427
if (numAmbientLights> 0 )
421
428
{
422
429
// ambient lights
423
430
for (int i = 0 ; i< numAmbientLights; ++ i)
424
431
{
425
- vec4 ambient_color = lightData.values[index ++ ];
432
+ vec4 ambient_color = lightData.values[lightDataIndex ++ ];
426
433
color += (baseColor.rgb * ambient_color.rgb) * (ambient_color.a * ambientOcclusion);
427
434
}
428
435
}
@@ -432,56 +439,39 @@ void main()
432
439
433
440
if (numDirectionalLights> 0 )
434
441
{
442
+ vec3 q1 = dFdx (eyePos);
443
+ vec3 q2 = dFdy (eyePos);
444
+ vec2 st1 = dFdx (texCoord0);
445
+ vec2 st2 = dFdy (texCoord0);
446
+
447
+ vec3 N = normalize (normalDir);
448
+ vec3 T = normalize (q1 * st2.t - q2 * st1.t);
449
+ vec3 B = - normalize (cross (N, T));
450
+
435
451
// directional lights
436
452
for (int i = 0 ; i< numDirectionalLights; ++ i)
437
453
{
438
- vec4 lightColor = lightData.values[index++ ];
439
- vec3 direction = - lightData.values[index++ ].xyz;
440
- vec4 shadowMapSettings = lightData.values[index++ ];
454
+ vec4 lightColor = lightData.values[lightDataIndex++ ];
455
+ vec3 direction = - lightData.values[lightDataIndex++ ].xyz;
441
456
442
457
float brightness = lightColor.a;
443
458
444
- // check shadow maps if required
445
- bool matched = false;
446
- while ((shadowMapSettings.r > 0.0 && brightness > brightnessCutoff) && ! matched)
447
- {
448
- mat4 sm_matrix = mat4 (lightData.values[index++ ],
449
- lightData.values[index++ ],
450
- lightData.values[index++ ],
451
- lightData.values[index++ ]);
452
-
453
- vec4 sm_tc = (sm_matrix) * vec4 (eyePos, 1.0 );
454
-
455
- if (sm_tc.x >= 0.0 && sm_tc.x <= 1.0 && sm_tc.y >= 0.0 && sm_tc.y <= 1.0 && sm_tc.z >= 0.0 /* && sm_tc.z <= 1.0*/ )
456
- {
457
- matched = true;
458
-
459
- float coverage = texture(shadowMaps, vec4 (sm_tc.st, shadowMapIndex, sm_tc.z)).r;
460
- brightness *= (1.0 - coverage);
461
-
462
- #ifdef SHADOWMAP_DEBUG
463
- if (shadowMapIndex== 0 ) color = vec3 (1.0 , 0.0 , 0.0 );
464
- else if (shadowMapIndex== 1 ) color = vec3 (0.0 , 1.0 , 0.0 );
465
- else if (shadowMapIndex== 2 ) color = vec3 (0.0 , 0.0 , 1.0 );
466
- else if (shadowMapIndex== 3 ) color = vec3 (1.0 , 1.0 , 0.0 );
467
- else if (shadowMapIndex== 4 ) color = vec3 (0.0 , 1.0 , 1.0 );
468
- else color = vec3 (1.0 , 1.0 , 1.0 );
469
- #endif
470
- }
471
-
472
- ++ shadowMapIndex;
473
- shadowMapSettings.r -= 1.0 ;
474
- }
459
+ // if light is too dim to effect the rendering skip it
460
+ if (brightness <= brightnessCutoff ) continue ;
475
461
476
- if (shadowMapSettings.r > 0.0 )
462
+ int shadowMapCount = int (lightData.values[lightDataIndex].r);
463
+ if (shadowMapCount > 0 )
477
464
{
478
- // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light
479
- // so subsequent light positions are correct.
480
- index += 4 * int (shadowMapSettings.r);
481
- shadowMapIndex += int (shadowMapSettings.r);
465
+ if (brightness > brightnessCutoff)
466
+ brightness *= (1.0 - calculateShadowCoverageForDirectionalLight(lightDataIndex, shadowMapIndex, T, B, color));
467
+
468
+ lightDataIndex += 1 + 8 * shadowMapCount;
469
+ shadowMapIndex += shadowMapCount;
482
470
}
471
+ else
472
+ lightDataIndex++ ;
483
473
484
- // if light is too dim/ shadowed to effect the rendering skip it
474
+ // if light is too shadowed to effect the rendering skip it
485
475
if (brightness <= brightnessCutoff ) continue ;
486
476
487
477
vec3 l = direction; // Vector from surface point to light
@@ -497,8 +487,8 @@ void main()
497
487
// point light
498
488
for (int i = 0 ; i< numPointLights; ++ i)
499
489
{
500
- vec4 lightColor = lightData.values[index ++ ];
501
- vec3 position = lightData.values[index ++ ].xyz;
490
+ vec4 lightColor = lightData.values[lightDataIndex ++ ];
491
+ vec3 position = lightData.values[lightDataIndex ++ ].xyz;
502
492
503
493
vec3 delta = position - eyePos;
504
494
float distance2 = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
@@ -514,21 +504,53 @@ void main()
514
504
515
505
if (numSpotLights> 0 )
516
506
{
507
+ vec3 q1 = dFdx (eyePos);
508
+ vec3 q2 = dFdy (eyePos);
509
+ vec2 st1 = dFdx (texCoord0);
510
+ vec2 st2 = dFdy (texCoord0);
511
+
512
+ vec3 N = normalize (normalDir);
513
+ vec3 T = normalize (q1 * st2.t - q2 * st1.t);
514
+ vec3 B = - normalize (cross (N, T));
515
+
517
516
// spot light
518
517
for (int i = 0 ; i< numSpotLights; ++ i)
519
518
{
520
- vec4 lightColor = lightData.values[index++ ];
521
- vec4 position_cosInnerAngle = lightData.values[index++ ];
522
- vec4 lightDirection_cosOuterAngle = lightData.values[index++ ];
519
+ vec4 lightColor = lightData.values[lightDataIndex++ ];
520
+ vec4 position_cosInnerAngle = lightData.values[lightDataIndex++ ];
521
+ vec4 lightDirection_cosOuterAngle = lightData.values[lightDataIndex++ ];
522
+
523
+ float brightness = lightColor.a;
524
+
525
+ // if light is too dim to effect the rendering skip it
526
+ if (brightness <= brightnessCutoff ) continue ;
523
527
524
528
vec3 delta = position_cosInnerAngle.xyz - eyePos;
525
529
float distance2 = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
526
- vec3 direction = delta / sqrt (distance2);
527
- float dot_lightdirection = - dot (lightDirection_cosOuterAngle.xyz, direction);
530
+ float dist = sqrt (distance2);
531
+
532
+ vec3 direction = delta / dist;
533
+
534
+ float dot_lightdirection = dot (lightDirection_cosOuterAngle.xyz, - direction);
535
+
536
+ int shadowMapCount = int (lightData.values[lightDataIndex].r);
537
+ if (shadowMapCount > 0 )
538
+ {
539
+ if (lightDirection_cosOuterAngle.w > dot_lightdirection)
540
+ brightness *= (1.0 - calculateShadowCoverageForSpotLight(lightDataIndex, shadowMapIndex, T, B, dist, color));
541
+
542
+ lightDataIndex += 1 + 8 * shadowMapCount;
543
+ shadowMapIndex += shadowMapCount;
544
+ }
545
+ else
546
+ lightDataIndex++ ;
547
+
548
+ // if light is too shadowed to effect the rendering skip it
549
+ if (brightness <= brightnessCutoff ) continue ;
528
550
529
551
vec3 l = direction; // Vector from surface point to light
530
552
vec3 h = normalize (l+ v); // Half vector between both l and v
531
- float scale = (lightColor.a * smoothstep (lightDirection_cosOuterAngle.w, position_cosInnerAngle.w, dot_lightdirection)) / distance2;
553
+ float scale = (brightness * smoothstep (lightDirection_cosOuterAngle.w, position_cosInnerAngle.w, dot_lightdirection)) / distance2;
532
554
533
555
color.rgb += BRDF(lightColor.rgb * scale, v, n, l, h, perceptualRoughness, metallic, specularEnvironmentR0, specularEnvironmentR90, alphaRoughness, diffuseColor, specularColor, ambientOcclusion);
534
556
}
@@ -559,5 +581,5 @@ void main()
559
581
}
560
582
}
561
583
562
- outColor = LINEARtoSRGB( vec4 (color, baseColor.a)) ;
584
+ outColor = vec4 (color, baseColor.a);
563
585
}
0 commit comments