mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-02 13:52:37 +00:00
2fbe44a72e
Other than the rather bad shadow acne, this is actually quake itself working nicely. Still need to get directional lights working for community maps, and all sorts of other little things (hide view model, show player, fix brush backfaces, etc).
71 lines
1.9 KiB
Text
71 lines
1.9 KiB
Text
#include "lighting.h"
|
|
#include "light_attach.h"
|
|
|
|
layout (location = 0) out vec4 frag_color;
|
|
|
|
layout (push_constant) uniform PushConstants {
|
|
uint queue;
|
|
};
|
|
|
|
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;
|
|
vec3 p = subpassLoad (position).rgb;
|
|
vec3 light = vec3 (0);
|
|
|
|
uint start = bitfieldExtract (queue, 0, 16);
|
|
uint count = bitfieldExtract (queue, 16, 16);
|
|
|
|
for (uint i = start; i < count; i++) {
|
|
uint id = lightIds[i];
|
|
LightData l = lights[id];
|
|
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);
|
|
|
|
uint id_data = renderer[id].id_data;
|
|
uint mat_id = bitfieldExtract (id_data, 0, 13);
|
|
uint map_id = bitfieldExtract (id_data, 13, 5);
|
|
uint layer = bitfieldExtract (id_data, 18, 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);
|
|
}
|