diff --git a/include/light/light.hh b/include/light/light.hh index 7bf81cf9..041e5375 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -392,6 +392,7 @@ public: setting_bool lightgrid; setting_vec3 lightgrid_dist; setting_bool lightgrid_force_cube; + setting_bool lightgrid_force_pot; setting_enum lightgrid_format; setting_func dirtdebug; diff --git a/light/light.cc b/light/light.cc index a03a8d2b..a6f2e9b1 100644 --- a/light/light.cc +++ b/light/light.cc @@ -317,6 +317,7 @@ light_settings::light_settings() lightgrid{this, "lightgrid", false, &experimental_group, "experimental LIGHTGRID bspx lump"}, lightgrid_dist{this, "lightgrid_dist", 32.f, 32.f, 32.f, &experimental_group, "distance between lightgrid sample points, in world units. controls lightgrid size."}, lightgrid_force_cube{this, "lightgrid_force_cube", false, &experimental_group, "force lightgrid to be a cube"}, + lightgrid_force_pot{this, "lightgrid_force_pot", false, &experimental_group, "force lightgrid to be a power of 2"}, lightgrid_format{this, "lightgrid_format", lightgrid_format_t::OCTREE, {{"cluster", lightgrid_format_t::CLUSTER}, {"uniform", lightgrid_format_t::UNIFORM}, {"octree", lightgrid_format_t::OCTREE}}, &experimental_group, "lightgrid BSPX lump to use"}, diff --git a/light/lightgrid.cc b/light/lightgrid.cc index 5618215c..11c67172 100644 --- a/light/lightgrid.cc +++ b/light/lightgrid.cc @@ -501,6 +501,15 @@ static aabb3f MakeCube(const aabb3f &input) centroid + qvec3f(new_size / 2)); } +static qvec3i MakePOT(const qvec3i& input) +{ + float x = static_cast(input[0]); + x = log2(x); + x = ceil(x); + x = exp2(x); + return qvec3i(static_cast(x)); +} + void LightGrid(bspdata_t *bspdata) { if (!light_options.lightgrid.value()) @@ -531,6 +540,26 @@ void LightGrid(bspdata_t *bspdata) ceil(world_size[2] / data.grid_dist[2]) }; + if (light_options.lightgrid_force_pot.value()) { + const auto old_grid_size = data.grid_size; + + logging::print("before making power of 2: data.grid_size: {}\n", data.grid_size); + data.grid_size = MakePOT(data.grid_size); + logging::print("after: data.grid_size: {}\n", data.grid_size); + + // adjust the grid mins to preserve the old center point + + qvec3f old_maxs = data.grid_mins + (old_grid_size * data.grid_dist); + // should always be >= old_maxs on each component + qvec3f new_maxs = data.grid_mins + (data.grid_size * data.grid_dist); + + qvec3f delta = (new_maxs - old_maxs) / 2; + + logging::print("shifting by -{}\n", delta); + + data.grid_mins -= delta; + } + data.grid_result.resize(data.grid_size[0] * data.grid_size[1] * data.grid_size[2]); data.occlusion.resize(data.grid_size[0] * data.grid_size[1] * data.grid_size[2]);