quakeforge/libs/video/renderer/vulkan/shader/lighting_main.finc
Bill Currie 7506117e43 [vulkan] Increase matrix id bits
I had missed that upping max lights to 2048 meant that up to 12288
matrices are needed for all the possible lights. This made it so the
light type could not be encoded in id_data, but the shaders never used
it anyway. This leaves one bit free.
2023-12-17 18:45:02 +09:00

69 lines
2.1 KiB
Text

layout (input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput color;
layout (input_attachment_index = 1, set = 2, binding = 1) uniform subpassInput emission;
layout (input_attachment_index = 2, set = 2, binding = 2) uniform subpassInput normal;
layout (input_attachment_index = 3, set = 2, binding = 3) uniform subpassInput position;
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);
}
void
main (void)
{
vec3 c = subpassLoad (color).rgb;
vec3 e = subpassLoad (emission).rgb;
vec3 n = subpassLoad (normal).rgb;
vec4 p = subpassLoad (position);
vec3 light = vec3 (0);
uint start = bitfieldExtract (queue, 0, 16);
uint end = start + bitfieldExtract (queue, 16, 16);
for (uint i = start; i < end; i++) {
uint id = lightIds[i];
LightData l = lights[id];
vec3 dir = l.position.xyz - l.position.w * p.xyz;
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);
uint id_data = renderer[id].id_data;
uint mat_id = bitfieldExtract (id_data, 0, 14);
uint map_id = bitfieldExtract (id_data, 14, 5);
uint layer = bitfieldExtract (id_data, 19, 11);
I *= shadow (map_id, layer, mat_id, p, l.position.xyz);
float namb = dot(l.direction.xyz, l.direction.xyz);
I *= spot_cone (l, incoming) * diffuse (incoming, n);
I = mix (1, I, namb);
vec4 col = l.color;
if (bitfieldExtract(id_data, 31, 1) == 0) {
col *= style[renderer[id].style];
}
light += I * col.w * col.xyz;
}
//light = max (light, minLight);
frag_color = vec4 (light, 1);
}