[vulkan] Implement light styles

Other than dealing with shader data alignment issues, that went well :).
Nicely, the implementation gets the explicit scaling out of the shader,
and allows for a directional flag.
This commit is contained in:
Bill Currie 2021-03-22 13:13:26 +09:00
parent 410fecd67b
commit 5173414d97
3 changed files with 29 additions and 10 deletions

View file

@ -38,7 +38,7 @@
typedef struct qfv_light_s {
vec3_t color;
float intensity;
int data;
vec3_t position;
float radius;
vec3_t direction;
@ -50,8 +50,10 @@ typedef struct qfv_lightleafset_s DARRAY_TYPE (int) qfv_lightleafset_t;
typedef struct qfv_lightvisset_s DARRAY_TYPE (byte) qfv_lightvisset_t;
#define NUM_LIGHTS 256
#define NUM_STYLES 64
typedef struct qfv_light_buffer_s {
float intensity[NUM_STYLES + 3];
int lightCount;
qfv_light_t lights[NUM_LIGHTS] __attribute__((aligned(16)));
} qfv_light_buffer_t;

View file

@ -7,7 +7,7 @@ layout (input_attachment_index = 3, set = 0, binding = 3) uniform subpassInput p
struct LightData {
vec3 color;
float intensity;
int data;// bits 0-6: intensity key (however, values 0-66)
vec3 position;
float radius;
vec3 direction;
@ -16,6 +16,8 @@ struct LightData {
layout (constant_id = 0) const int MaxLights = 128;
layout (set = 1, binding = 0) uniform Lights {
vec4 intensity[16]; // 64 floats
vec3 intensity2;
int lightCount;
LightData lights[MaxLights];
};
@ -32,9 +34,12 @@ calc_light (LightData light, vec3 position, vec3 normal)
float lightdot = dot (incoming, normal);
float r = light.radius;
float intensity = light.intensity * step (d, r);
intensity *= smoothstep (spotdot, 1 - (1 - spotdot) * 0.995, light.cone) * clamp (lightdot, 0, 1);
return light.color * intensity * (r - d);
int style = light.data & 0x7f;
// deliberate array index error: access intensity2 as well
float i = intensity[style / 4][style % 4];
i *= step (d, r) * clamp (lightdot, 0, 1);
i *= smoothstep (spotdot, 1 - (1 - spotdot) * 0.995, light.cone);
return light.color * i * (r - d);
}
void
@ -51,5 +56,5 @@ main (void)
light += calc_light (lights[i], p, n);
}
}
frag_color = vec4 (c * light / 255.0, 1);
frag_color = vec4 (c * light, 1);
}

View file

@ -121,6 +121,14 @@ update_lights (vulkan_ctx_t *ctx)
qfv_light_buffer_t *light_data = QFV_PacketExtend (packet,
sizeof (*light_data));
for (int i = 0; i < NUM_STYLES; i++) {
light_data->intensity[i] = d_lightstylevalue[i] / 65536.0;
}
// dynamic lights seem a tad fiant, so 16x map lights
light_data->intensity[64] = 1 / 16.0;
light_data->intensity[65] = 1 / 16.0;
light_data->intensity[66] = 1 / 16.0;
light_data->lightCount = 0;
R_FindNearLights (r_origin, NUM_LIGHTS - 1, lights);
for (int i = 0; i < NUM_LIGHTS - 1; i++) {
@ -131,7 +139,7 @@ update_lights (vulkan_ctx_t *ctx)
VectorCopy (lights[i]->color, light_data->lights[i].color);
VectorCopy (lights[i]->origin, light_data->lights[i].position);
light_data->lights[i].radius = lights[i]->radius;
light_data->lights[i].intensity = 16;
light_data->lights[i].data = 64; // default dynamic light
VectorZero (light_data->lights[i].direction);
light_data->lights[i].cone = 1;
}
@ -380,7 +388,7 @@ parse_light (qfv_light_t *light, const plitem_t *entity,
Sys_Printf ("}\n");*/
light->cone = 1;
light->intensity = 1;
light->data = 0;
light->radius = 300;
VectorSet (1, 1, 1, light->color);
@ -411,6 +419,10 @@ parse_light (qfv_light_t *light, const plitem_t *entity,
light->radius = atof (str);
}
if ((str = PL_String (PL_ObjectForKey (entity, "style")))) {
light->data = atoi (str) & 0x3f;
}
if ((str = PL_String (PL_ObjectForKey (entity, "color")))
|| (str = PL_String (PL_ObjectForKey (entity, "_color")))) {
sscanf (str, "%f %f %f", VectorExpandAddr (light->color));
@ -467,8 +479,8 @@ Vulkan_LoadLights (model_t *model, const char *entity_data, vulkan_ctx_t *ctx)
mleaf_t *leaf = Mod_PointInLeaf (&light.position[0],
model);
DARRAY_APPEND (&lctx->lightleafs, leaf - model->brush.leafs);
printf ("[%g, %g, %g] %g, [%g %g %g] %g, [%g %g %g] %g, %zd\n",
VectorExpand (light.color), light.intensity,
printf ("[%g, %g, %g] %d, [%g %g %g] %g, [%g %g %g] %g, %zd\n",
VectorExpand (light.color), light.data,
VectorExpand (light.position), light.radius,
VectorExpand (light.direction), light.cone,
leaf - model->brush.leafs);