Skip to content

Commit e48d973

Browse files
committed
2 parents c401301 + 3c569c0 commit e48d973

File tree

1 file changed

+101
-79
lines changed

1 file changed

+101
-79
lines changed

data/shaders/custom_pbr.frag

Lines changed: 101 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#version 450
22
#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
47

58
#define VIEW_DESCRIPTOR_SET 1
69
#define MATERIAL_DESCRIPTOR_SET 2
@@ -16,8 +19,8 @@ const float c_MinRoughness = 0.04;
1619
layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap;
1720
#endif
1821

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;
2124
#endif
2225

2326
#ifdef VSG_NORMAL_MAP
@@ -36,6 +39,10 @@ layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap
3639
layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap;
3740
#endif
3841

42+
#ifdef VSG_METALLROUGHNESS_MAP
43+
layout(set = MATERIAL_DESCRIPTOR_SET, binding = 6) uniform sampler2D mrMap;
44+
#endif
45+
3946
layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData
4047
{
4148
vec4 baseColorFactor;
@@ -49,13 +56,12 @@ layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData
4956
} pbr;
5057

5158
// ViewDependentState
59+
layout(constant_id = 3) const int lightDataSize = 256;
5260
layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData
5361
{
54-
vec4 values[2048];
62+
vec4 values[lightDataSize];
5563
} lightData;
5664

57-
layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps;
58-
5965
// Custom state
6066
layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform Fog
6167
{
@@ -69,7 +75,9 @@ layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform Fog
6975
layout(location = 0) in vec3 eyePos;
7076
layout(location = 1) in vec3 normalDir;
7177
layout(location = 2) in vec4 vertexColor;
78+
#ifndef VSG_POINT_SPRITE
7279
layout(location = 3) in vec2 texCoord0;
80+
#endif
7381
layout(location = 5) in vec3 viewDir;
7482

7583
layout(location = 0) out vec4 outColor;
@@ -95,19 +103,6 @@ struct PBRInfo
95103
vec3 specularColor; // color contribution from specular lighting
96104
};
97105

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-
111106
float rcp(const in float value)
112107
{
113108
return 1.0 / value;
@@ -118,6 +113,9 @@ float pow5(const in float value)
118113
return value * value * value * value * value;
119114
}
120115

116+
// include the calculateShadowCoverageForDirectionalLight(..) implementation
117+
#include "shadows.glsl"
118+
121119
// Find the normal for this fragment, pulling either from a predefined normal map
122120
// or from the interpolated mesh normal and tangent attributes.
123121
vec3 getNormal()
@@ -291,7 +289,7 @@ vec3 BRDF(vec3 u_LightColor, vec3 v, vec3 n, vec3 l, vec3 h, float perceptualRou
291289
color *= ao;
292290

293291
#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;
295293
#else
296294
vec3 emissive = pbr.emissiveFactor.rgb;
297295
#endif
@@ -321,6 +319,10 @@ void main()
321319
{
322320
float brightnessCutoff = 0.001;
323321

322+
#ifdef VSG_POINT_SPRITE
323+
vec2 texCoord0 = gl_PointCoord.xy;
324+
#endif
325+
324326
float perceptualRoughness = 0.0;
325327
float metallic;
326328
vec3 diffuseColor;
@@ -335,28 +337,33 @@ void main()
335337
float v = texture(diffuseMap, texCoord0.st).s * pbr.baseColorFactor;
336338
baseColor = vertexColor * vec4(v, v, v, 1.0);
337339
#else
338-
baseColor = vertexColor * SRGBtoLINEAR(texture(diffuseMap, texCoord0)) * pbr.baseColorFactor;
340+
baseColor = vertexColor * texture(diffuseMap, texCoord0) * pbr.baseColorFactor;
339341
#endif
340342
#else
341343
baseColor = vertexColor * pbr.baseColorFactor;
342344
#endif
343345

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
349356

350357
#ifdef VSG_WORKFLOW_SPECGLOSS
351358
#ifdef VSG_DIFFUSE_MAP
352-
vec4 diffuse = SRGBtoLINEAR(texture(diffuseMap, texCoord0));
359+
vec4 diffuse = texture(diffuseMap, texCoord0);
353360
#else
354361
vec4 diffuse = vec4(1.0);
355362
#endif
356363

357364
#ifdef VSG_SPECULAR_MAP
358365
vec4 specular_texel = texture(specularMap, texCoord0);
359-
vec3 specular = SRGBtoLINEAR(specular_texel).rgb;
366+
vec3 specular = specular_texel.rgb;
360367
perceptualRoughness = 1.0 - specular_texel.a;
361368
#else
362369
vec3 specular = vec3(0.0);
@@ -415,14 +422,14 @@ void main()
415422
int numDirectionalLights = int(lightNums[1]);
416423
int numPointLights = int(lightNums[2]);
417424
int numSpotLights = int(lightNums[3]);
418-
int index = 1;
425+
int lightDataIndex = 1;
419426

420427
if (numAmbientLights>0)
421428
{
422429
// ambient lights
423430
for(int i = 0; i<numAmbientLights; ++i)
424431
{
425-
vec4 ambient_color = lightData.values[index++];
432+
vec4 ambient_color = lightData.values[lightDataIndex++];
426433
color += (baseColor.rgb * ambient_color.rgb) * (ambient_color.a * ambientOcclusion);
427434
}
428435
}
@@ -432,56 +439,39 @@ void main()
432439

433440
if (numDirectionalLights>0)
434441
{
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+
435451
// directional lights
436452
for(int i = 0; i<numDirectionalLights; ++i)
437453
{
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;
441456

442457
float brightness = lightColor.a;
443458

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;
475461

476-
if (shadowMapSettings.r > 0.0)
462+
int shadowMapCount = int(lightData.values[lightDataIndex].r);
463+
if (shadowMapCount > 0)
477464
{
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;
482470
}
471+
else
472+
lightDataIndex++;
483473

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
485475
if (brightness <= brightnessCutoff ) continue;
486476

487477
vec3 l = direction; // Vector from surface point to light
@@ -497,8 +487,8 @@ void main()
497487
// point light
498488
for(int i = 0; i<numPointLights; ++i)
499489
{
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;
502492

503493
vec3 delta = position - eyePos;
504494
float distance2 = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
@@ -514,21 +504,53 @@ void main()
514504

515505
if (numSpotLights>0)
516506
{
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+
517516
// spot light
518517
for(int i = 0; i<numSpotLights; ++i)
519518
{
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;
523527

524528
vec3 delta = position_cosInnerAngle.xyz - eyePos;
525529
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;
528550

529551
vec3 l = direction; // Vector from surface point to light
530552
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;
532554

533555
color.rgb += BRDF(lightColor.rgb * scale, v, n, l, h, perceptualRoughness, metallic, specularEnvironmentR0, specularEnvironmentR90, alphaRoughness, diffuseColor, specularColor, ambientOcclusion);
534556
}
@@ -559,5 +581,5 @@ void main()
559581
}
560582
}
561583

562-
outColor = LINEARtoSRGB(vec4(color, baseColor.a)) ;
584+
outColor = vec4(color, baseColor.a);
563585
}

0 commit comments

Comments
 (0)