[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 { typedef struct qfv_light_s {
vec3_t color; vec3_t color;
float intensity; int data;
vec3_t position; vec3_t position;
float radius; float radius;
vec3_t direction; 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; typedef struct qfv_lightvisset_s DARRAY_TYPE (byte) qfv_lightvisset_t;
#define NUM_LIGHTS 256 #define NUM_LIGHTS 256
#define NUM_STYLES 64
typedef struct qfv_light_buffer_s { typedef struct qfv_light_buffer_s {
float intensity[NUM_STYLES + 3];
int lightCount; int lightCount;
qfv_light_t lights[NUM_LIGHTS] __attribute__((aligned(16))); qfv_light_t lights[NUM_LIGHTS] __attribute__((aligned(16)));
} qfv_light_buffer_t; } qfv_light_buffer_t;

View file

@ -7,7 +7,7 @@ layout (input_attachment_index = 3, set = 0, binding = 3) uniform subpassInput p
struct LightData { struct LightData {
vec3 color; vec3 color;
float intensity; int data;// bits 0-6: intensity key (however, values 0-66)
vec3 position; vec3 position;
float radius; float radius;
vec3 direction; vec3 direction;
@ -16,6 +16,8 @@ struct LightData {
layout (constant_id = 0) const int MaxLights = 128; layout (constant_id = 0) const int MaxLights = 128;
layout (set = 1, binding = 0) uniform Lights { layout (set = 1, binding = 0) uniform Lights {
vec4 intensity[16]; // 64 floats
vec3 intensity2;
int lightCount; int lightCount;
LightData lights[MaxLights]; LightData lights[MaxLights];
}; };
@ -32,9 +34,12 @@ calc_light (LightData light, vec3 position, vec3 normal)
float lightdot = dot (incoming, normal); float lightdot = dot (incoming, normal);
float r = light.radius; float r = light.radius;
float intensity = light.intensity * step (d, r); int style = light.data & 0x7f;
intensity *= smoothstep (spotdot, 1 - (1 - spotdot) * 0.995, light.cone) * clamp (lightdot, 0, 1); // deliberate array index error: access intensity2 as well
return light.color * intensity * (r - d); 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 void
@ -51,5 +56,5 @@ main (void)
light += calc_light (lights[i], p, n); 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, qfv_light_buffer_t *light_data = QFV_PacketExtend (packet,
sizeof (*light_data)); 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; light_data->lightCount = 0;
R_FindNearLights (r_origin, NUM_LIGHTS - 1, lights); R_FindNearLights (r_origin, NUM_LIGHTS - 1, lights);
for (int i = 0; i < NUM_LIGHTS - 1; i++) { 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]->color, light_data->lights[i].color);
VectorCopy (lights[i]->origin, light_data->lights[i].position); VectorCopy (lights[i]->origin, light_data->lights[i].position);
light_data->lights[i].radius = lights[i]->radius; 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); VectorZero (light_data->lights[i].direction);
light_data->lights[i].cone = 1; light_data->lights[i].cone = 1;
} }
@ -380,7 +388,7 @@ parse_light (qfv_light_t *light, const plitem_t *entity,
Sys_Printf ("}\n");*/ Sys_Printf ("}\n");*/
light->cone = 1; light->cone = 1;
light->intensity = 1; light->data = 0;
light->radius = 300; light->radius = 300;
VectorSet (1, 1, 1, light->color); VectorSet (1, 1, 1, light->color);
@ -411,6 +419,10 @@ parse_light (qfv_light_t *light, const plitem_t *entity,
light->radius = atof (str); 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"))) if ((str = PL_String (PL_ObjectForKey (entity, "color")))
|| (str = PL_String (PL_ObjectForKey (entity, "_color")))) { || (str = PL_String (PL_ObjectForKey (entity, "_color")))) {
sscanf (str, "%f %f %f", VectorExpandAddr (light->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], mleaf_t *leaf = Mod_PointInLeaf (&light.position[0],
model); model);
DARRAY_APPEND (&lctx->lightleafs, leaf - model->brush.leafs); DARRAY_APPEND (&lctx->lightleafs, leaf - model->brush.leafs);
printf ("[%g, %g, %g] %g, [%g %g %g] %g, [%g %g %g] %g, %zd\n", printf ("[%g, %g, %g] %d, [%g %g %g] %g, [%g %g %g] %g, %zd\n",
VectorExpand (light.color), light.intensity, VectorExpand (light.color), light.data,
VectorExpand (light.position), light.radius, VectorExpand (light.position), light.radius,
VectorExpand (light.direction), light.cone, VectorExpand (light.direction), light.cone,
leaf - model->brush.leafs); leaf - model->brush.leafs);