store leaves on surf instead of surface light

This commit is contained in:
Jonathan 2024-03-08 23:54:59 -05:00
parent cb89691b54
commit 3d419853d3
5 changed files with 45 additions and 33 deletions

View File

@ -133,6 +133,7 @@ struct lightsurf_t
the pvs at each of the sample points
*/
std::vector<uint8_t> pvs;
std::vector<const mleaf_t *> leaves;
// output width * extra
int width;

View File

@ -47,7 +47,6 @@ struct surfacelight_t
std::optional<float> minlight_scale;
std::vector<qvec3f> points;
std::vector<const mleaf_t *> leaves;
// Surface light settings...
struct per_style_t

View File

@ -109,12 +109,8 @@ static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys &
// Init bbox...
if (light_options.visapprox.value() == visapprox_t::RAYS) {
l->bounds = EstimateVisibleBoundsAtPoint(facemidpoint);
}
for (auto &pt : l->points) {
if (light_options.visapprox.value() == visapprox_t::VIS) {
l->leaves.push_back(Light_PointInLeaf(bsp, pt));
} else if (light_options.visapprox.value() == visapprox_t::RAYS) {
for (auto &pt : l->points) {
l->bounds += EstimateVisibleBoundsAtPoint(pt);
}
}

View File

@ -506,29 +506,37 @@ static const std::vector<uint8_t> *Mod_LeafPvs(const mbsp_t *bsp, const mleaf_t
static void CalcPvs(const mbsp_t *bsp, lightsurf_t *lightsurf)
{
const int pvssize = DecompressedVisSize(bsp);
const mleaf_t *lastleaf = nullptr;
// set defaults
lightsurf->pvs.clear();
if (!bsp->dvis.bits.size()) {
return;
}
const int pvssize = DecompressedVisSize(bsp);
// set lightsurf->pvs
uint8_t *pointpvs = (uint8_t *)alloca(pvssize);
lightsurf->pvs.resize(pvssize);
for (auto &sample : lightsurf->samples) {
const mleaf_t *leaf = Light_PointInLeaf(bsp, sample.point);
if (lightsurf->modelinfo->isWorld()) {
size_t face_index = lightsurf->face - bsp->dfaces.data();
/* most/all of the surface points are probably in the same leaf */
if (leaf == lastleaf)
continue;
for (auto &leaf : bsp->dleafs) {
for (size_t surf = 0; surf < leaf.nummarksurfaces; surf++) {
if (bsp->dleaffaces[leaf.firstmarksurface + surf] == face_index) {
lightsurf->leaves.push_back(&leaf);
}
}
}
} else {
for (auto &sample : lightsurf->samples) {
const mleaf_t *leaf = Light_PointInLeaf(bsp, sample.point);
lastleaf = leaf;
if (std::find(lightsurf->leaves.begin(), lightsurf->leaves.end(), leaf) == lightsurf->leaves.end()) {
lightsurf->leaves.push_back(leaf);
}
}
}
for (auto &leaf : lightsurf->leaves) {
/* copy the pvs for this leaf into pointpvs */
Mod_LeafPvs(bsp, leaf, pointpvs);
@ -547,6 +555,8 @@ static void CalcPvs(const mbsp_t *bsp, lightsurf_t *lightsurf)
lightsurf->pvs[j] |= pointpvs[j];
}
}
lightsurf->leaves.shrink_to_fit();
}
static std::unique_ptr<lightsurf_t> Lightsurf_Init(const modelinfo_t *modelinfo, const settings::worldspawn_keys &cfg,
@ -1978,6 +1988,20 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf,
return qv::gate(color, (float)bouncelight_gate);
}
static bool
SurfaceLight_VisCull(const mbsp_t *bsp, const std::vector<uint8_t> *pvs, const lightsurf_t *lightsurf_b)
{
if (pvs && light_options.visapprox.value() == visapprox_t::VIS) {
for (auto &leaf : lightsurf_b->leaves) {
if (VisCullEntity(bsp, *pvs, leaf)) {
return true;
}
}
}
return false;
}
static void // mxd
LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t *lightmaps, std::optional<size_t> bounce_depth,
const float &standard_scale, const float &sky_scale, const float &hotspot_clamp)
@ -1999,17 +2023,14 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t
continue;
else if (SurfaceLight_SphereCull(&vpl, lightsurf, vpl_setting, surflight_gate, hotspot_clamp))
continue;
else if (SurfaceLight_VisCull(bsp, &lightsurf->pvs, surf_ptr))
continue;
raystream_occlusion_t &rs = occlusion_stream;
rs.clearPushedRays();
for (int c = 0; c < vpl.points.size(); c++) {
if (light_options.visapprox.value() == visapprox_t::VIS &&
VisCullEntity(bsp, lightsurf->pvs, vpl.leaves[c])) {
continue;
}
for (int i = 0; i < lightsurf->samples.size(); i++) {
const auto &sample = lightsurf->samples[i];
@ -2099,11 +2120,11 @@ LightPoint_SurfaceLight(const mbsp_t *bsp, const std::vector<uint8_t> *pvs, rays
for (const auto &surf : EmissiveLightSurfaces()) {
const surfacelight_t &vpl = *surf->vpl;
for (int c = 0; c < vpl.points.size(); c++) {
if (light_options.visapprox.value() == visapprox_t::VIS && pvs && VisCullEntity(bsp, *pvs, vpl.leaves[c])) {
continue;
}
if (SurfaceLight_VisCull(bsp, pvs, surf)) {
continue;
}
for (int c = 0; c < vpl.points.size(); c++) {
// 1 ray
for (auto &vpl_settings : vpl.styles) {
if (vpl_settings.bounce_level.has_value() != bounce)

View File

@ -23,7 +23,6 @@ See file, 'COPYING', for details.
#include <cassert>
#include <light/entities.hh> // for FixLightOnFace
#include <light/trace.hh> // for Light_PointInLeaf
#include <light/light.hh>
#include <light/ltface.hh>
@ -172,12 +171,8 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys
// Init bbox...
if (light_options.visapprox.value() == visapprox_t::RAYS) {
l->bounds = EstimateVisibleBoundsAtPoint(l->pos);
}
for (auto &pt : l->points) {
if (light_options.visapprox.value() == visapprox_t::VIS) {
l->leaves.push_back(Light_PointInLeaf(bsp, pt));
} else if (light_options.visapprox.value() == visapprox_t::RAYS) {
for (auto &pt : l->points) {
l->bounds += EstimateVisibleBoundsAtPoint(pt);
}
}