mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[vulkan] Pre-compute the sun's PVS
Any sun (a directional light) is in the outside node, which due to not having its own PVS data is visible to all nodes, but that's a tad excessive. However, any leaf node with sky surfaces will potentially see any suns, and leaf nodes with no sky surfaces will see the sun only if they can see a leaf that does have sky surfaces. This can be quite expensive to calculate (already known to be moderately expensive for just the camera leaf node (singular!) when checking for in-map lights)
This commit is contained in:
parent
3ef89583af
commit
924c970868
2 changed files with 29 additions and 11 deletions
|
@ -124,6 +124,7 @@ typedef struct lightingctx_s {
|
||||||
qfv_imageset_t lightimages;
|
qfv_imageset_t lightimages;
|
||||||
qfv_lightintset_t lightlayers;
|
qfv_lightintset_t lightlayers;
|
||||||
qfv_imageviewset_t lightviews;
|
qfv_imageviewset_t lightviews;
|
||||||
|
byte sun_pvs[MAX_MAP_LEAFS];
|
||||||
} lightingctx_t;
|
} lightingctx_t;
|
||||||
|
|
||||||
struct vulkan_ctx_s;
|
struct vulkan_ctx_s;
|
||||||
|
|
|
@ -67,6 +67,18 @@
|
||||||
|
|
||||||
static vec4f_t ref_direction = { 0, 0, 1, 0 };
|
static vec4f_t ref_direction = { 0, 0, 1, 0 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
expand_pvs (byte *pvs, model_t *model)
|
||||||
|
{
|
||||||
|
byte base_pvs[MAP_PVS_BYTES];
|
||||||
|
memcpy (base_pvs, pvs, sizeof (base_pvs));
|
||||||
|
for (int i = 0; i < model->brush.numleafs; i++) {
|
||||||
|
if (base_pvs[(unsigned) i / 8] & (1 << ((unsigned) i % 8))) {
|
||||||
|
Mod_LeafPVS_mix (model->brush.leafs + i + 1, model, 0, pvs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_visible_lights (vulkan_ctx_t *ctx)
|
find_visible_lights (vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
@ -84,17 +96,10 @@ find_visible_lights (vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
if (leaf != lframe->leaf) {
|
if (leaf != lframe->leaf) {
|
||||||
//double start = Sys_DoubleTime ();
|
//double start = Sys_DoubleTime ();
|
||||||
byte pvs[MAP_PVS_BYTES];
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
Mod_LeafPVS_set (leaf, model, 0, pvs);
|
Mod_LeafPVS_set (leaf, model, 0, lframe->pvs);
|
||||||
memcpy (lframe->pvs, pvs, sizeof (pvs));
|
expand_pvs (lframe->pvs, model);
|
||||||
for (int i = 0; i < model->brush.numleafs; i++) {
|
|
||||||
if (pvs[i / 8] & (1 << (i % 8))) {
|
|
||||||
Mod_LeafPVS_mix (model->brush.leafs + i + 1, model, 0,
|
|
||||||
lframe->pvs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < model->brush.numleafs; i++) {
|
for (int i = 0; i < model->brush.numleafs; i++) {
|
||||||
if (lframe->pvs[i / 8] & (1 << (i % 8))) {
|
if (lframe->pvs[i / 8] & (1 << (i % 8))) {
|
||||||
flags |= model->brush.leaf_flags[i + 1];
|
flags |= model->brush.leaf_flags[i + 1];
|
||||||
|
@ -535,13 +540,14 @@ sun_vector (const vec_t *ang, vec_t *vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_sun (lightingctx_t *lctx, plitem_t *entity)
|
parse_sun (lightingctx_t *lctx, plitem_t *entity, model_t *model)
|
||||||
{
|
{
|
||||||
qfv_light_t light = {};
|
qfv_light_t light = {};
|
||||||
float sunlight;
|
float sunlight;
|
||||||
//float sunlight2;
|
//float sunlight2;
|
||||||
vec3_t sunangle = { 0, -90, 0 };
|
vec3_t sunangle = { 0, -90, 0 };
|
||||||
|
|
||||||
|
memset (lctx->sun_pvs, 0, MAX_MAP_LEAFS);
|
||||||
sunlight = parse_float (PL_String (PL_ObjectForKey (entity,
|
sunlight = parse_float (PL_String (PL_ObjectForKey (entity,
|
||||||
"_sunlight")), 0);
|
"_sunlight")), 0);
|
||||||
//sunlight2 = parse_float (PL_String (PL_ObjectForKey (entity,
|
//sunlight2 = parse_float (PL_String (PL_ObjectForKey (entity,
|
||||||
|
@ -558,6 +564,17 @@ parse_sun (lightingctx_t *lctx, plitem_t *entity)
|
||||||
light.cone = 1;
|
light.cone = 1;
|
||||||
DARRAY_APPEND (&lctx->lights, light);
|
DARRAY_APPEND (&lctx->lights, light);
|
||||||
DARRAY_APPEND (&lctx->lightleafs, -1);
|
DARRAY_APPEND (&lctx->lightleafs, -1);
|
||||||
|
|
||||||
|
// Any leaf with sky surfaces can potentially see the sun, thus put
|
||||||
|
// the sun "in" every leaf with a sky surface
|
||||||
|
for (int l = 0; l < model->brush.numleafs; l++) {
|
||||||
|
if (model->brush.leaf_flags[l] & SURF_DRAWSKY) {
|
||||||
|
lctx->sun_pvs[l / 8] |= 1 << (l % 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// any leaf visible from a leaf with a sky surface (and thus the sun)
|
||||||
|
// can receive shadows from the sun
|
||||||
|
expand_pvs (lctx->sun_pvs, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -934,7 +951,7 @@ Vulkan_LoadLights (model_t *model, const char *entity_data, vulkan_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
if (strequal (classname, "worldspawn")) {
|
if (strequal (classname, "worldspawn")) {
|
||||||
// parse_sun can add many lights
|
// parse_sun can add many lights
|
||||||
parse_sun (lctx, entity);
|
parse_sun (lctx, entity, model);
|
||||||
} else if (strnequal (classname, "light", 5)) {
|
} else if (strnequal (classname, "light", 5)) {
|
||||||
qfv_light_t light = {};
|
qfv_light_t light = {};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue