From 5173414d97b6093e795a64d24ee9182dad3ca9d5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 22 Mar 2021 13:13:26 +0900 Subject: [PATCH] [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. --- include/QF/Vulkan/qf_lighting.h | 4 +++- .../renderer/vulkan/shader/lighting.frag | 15 +++++++++----- libs/video/renderer/vulkan/vulkan_lighting.c | 20 +++++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index c269feaae..f6aa67a94 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -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; diff --git a/libs/video/renderer/vulkan/shader/lighting.frag b/libs/video/renderer/vulkan/shader/lighting.frag index b756dd879..98f5b20a6 100644 --- a/libs/video/renderer/vulkan/shader/lighting.frag +++ b/libs/video/renderer/vulkan/shader/lighting.frag @@ -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); } diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index b1eecf3d3..56c14387a 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -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);