mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
It's not perfect (double fog on translucent surfaces, the scatter/absorption isn't right, and no local lighting on the fog itself), but it at least seems to look ok.
74 lines
2.2 KiB
Text
74 lines
2.2 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);
|
|
}
|
|
|
|
#include "fog.finc"
|
|
|
|
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];
|
|
}
|
|
if (fog.w > 0) {
|
|
col = FogTransmit (col, fog, r[1]);
|
|
}
|
|
light += I * col.w * col.xyz;
|
|
}
|
|
//light = max (light, minLight);
|
|
|
|
frag_color = vec4 (light, 1);
|
|
}
|