quakeforge/libs/video/renderer/vulkan/shader/lighting.frag
Bill Currie 27de599ac4 [vulkan] Resurrect the shadow map resource creation
However, this time it doesn't modify the light array when it sorts the
lights by size since the lights are now located before the renderer gets
to see them, and having the fix up the light leafs array would be too
painful (and probably the completely wrong thing to do anyway: the light
array should be treated as constant by the renderer). 1.6GB of memory
for gmsp3v2's lights (a little better than marcher: more smaller lights?).

For reference:
gmsp3v2: shadow maps: 8330 layers in 29 images: 1647706112
marcher: shadow maps: 2440 layers in 11 images: 2358575104
2022-05-19 13:26:45 +09:00

122 lines
3.6 KiB
GLSL

#version 450
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput depth;
layout (input_attachment_index = 1, set = 0, binding = 1) uniform subpassInput color;
layout (input_attachment_index = 2, set = 0, binding = 2) uniform subpassInput emission;
layout (input_attachment_index = 3, set = 0, binding = 3) uniform subpassInput normal;
layout (input_attachment_index = 4, set = 0, binding = 4) uniform subpassInput position;
struct LightData {
vec4 color; // .a is intensity
vec4 position; // .w = 0 -> directional, .w = 1 -> point/cone
vec4 direction; // .w = -cos(cone_angle/2) (1 for omni/dir)
vec4 attenuation;
};
#define StyleMask 0x07f
#define ModelMask 0x380
#define ShadowMask 0xc00
#define LM_LINEAR (0 << 7) // light - dist (or radius + dist if -ve)
#define LM_INVERSE (1 << 7) // distFactor1 * light / dist
#define LM_INVERSE2 (2 << 7) // distFactor2 * light / (dist * dist)
#define LM_INFINITE (3 << 7) // light
#define LM_AMBIENT (4 << 7) // light
#define LM_INVERSE3 (5 << 7) // distFactor2 * light / (dist + distFactor2)**2
#define ST_NONE (0 << 10) // no shadows
#define ST_PLANE (1 << 10) // single plane shadow map (small spotlight)
#define ST_CASCADE (2 << 10) // cascaded shadow maps
#define ST_CUBE (3 << 10) // cubemap (omni, large spotlight)
layout (constant_id = 0) const int MaxLights = 768;
layout (set = 2, binding = 0) uniform sampler2DArrayShadow shadowCascade[MaxLights];
layout (set = 2, binding = 0) uniform sampler2DShadow shadowPlane[MaxLights];
layout (set = 2, binding = 0) uniform samplerCubeShadow shadowCube[MaxLights];
layout (set = 1, binding = 0) uniform Lights {
LightData lights[MaxLights];
int lightCount;
//mat4 shadowMat[MaxLights];
//vec4 shadowCascale[MaxLights];
};
layout (location = 0) out vec4 frag_color;
float
spot_cone (LightData light, vec3 incoming)
{
vec3 dir = light.direction.xyz;
float cone = light.direction.w;
float spotdot = dot (incoming, dir);
return 1 - smoothstep (cone, .995 * cone + 0.005, spotdot);
}
float
diffuse (vec3 incoming, vec3 normal)
{
float lightdot = dot (incoming, normal);
return clamp (lightdot, 0, 1);
}
float
shadow_cascade (sampler2DArrayShadow map)
{
return 1;
}
float
shadow_plane (sampler2DShadow map)
{
return 1;
}
float
shadow_cube (samplerCubeShadow map)
{
return 1;
}
void
main (void)
{
//float d = subpassLoad (depth).r;
vec3 c = subpassLoad (color).rgb;
vec3 e = subpassLoad (emission).rgb;
vec3 n = subpassLoad (normal).rgb;
vec3 p = subpassLoad (position).rgb;
vec3 light = vec3 (0);
//vec3 minLight = vec3 (0);
for (int i = 0; i < lightCount; i++) {
LightData l = lights[i];
vec3 dir = l.position.xyz - l.position.w * p;
float r2 = dot (dir, dir);
vec4 a = l.attenuation;
if (l.position.w * a.w * a.w * r2 >= 1) {
continue;
}
vec4 r = vec4 (r2, sqrt(r2), 1, 0);
vec3 incoming = dir / r.y;
float I = (1 - a.w * r.y) / dot (a, r);
/*int shadow = lights[i].data & ShadowMask;
if (shadow == ST_CASCADE) {
I *= shadow_cascade (shadowCascade[i]);
} else if (shadow == ST_PLANE) {
I *= shadow_plane (shadowPlane[i]);
} else if (shadow == ST_CUBE) {
I *= shadow_cube (shadowCube[i]);
}*/
float namb = dot(l.direction.xyz, l.direction.xyz);
I *= spot_cone (l, incoming) * diffuse (incoming, n);
I = mix (1, I, namb);
light += I * l.color.w * l.color.xyz;
}
//light = max (light, minLight);
frag_color = vec4 (c * light + e, 1);
}