light: write styles into the experimental lightgrid lump
This commit is contained in:
parent
89fa416708
commit
2cc513848b
|
|
@ -57,5 +57,21 @@ void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf);
|
|||
void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup,
|
||||
bspx_decoupled_lm_perface *facesup_decoupled, lightsurf_t *lightsurf, const faceextents_t &extents,
|
||||
const faceextents_t &output_extents);
|
||||
qvec3d CalcLightgridAtPoint(const mbsp_t *bsp, const qvec3d &world_point);
|
||||
|
||||
struct lightgrid_sample_t {
|
||||
bool used = false;
|
||||
int style = 0;
|
||||
qvec3d color {};
|
||||
|
||||
qvec3b round_to_int() const;
|
||||
};
|
||||
|
||||
struct lightgrid_samples_t {
|
||||
std::array<lightgrid_sample_t, 4> samples_by_style;
|
||||
|
||||
void add(const qvec3d &color, int style);
|
||||
int used_styles() const;
|
||||
};
|
||||
|
||||
lightgrid_samples_t CalcLightgridAtPoint(const mbsp_t *bsp, const qvec3d &world_point);
|
||||
void ResetLtFace();
|
||||
|
|
|
|||
|
|
@ -1064,10 +1064,9 @@ static void LightGrid(bspdata_t *bspdata)
|
|||
// number of grid points on each axis
|
||||
const qvec3i grid_size = {GRIDSIZE, GRIDSIZE, GRIDSIZE};
|
||||
const qvec3f grid_mins = bsp.dmodels[0].mins;
|
||||
const uint8_t num_styles = 1;
|
||||
|
||||
std::vector<uint8_t> grid_result;
|
||||
grid_result.resize(GRIDSIZE * GRIDSIZE * GRIDSIZE * 3);
|
||||
std::vector<lightgrid_samples_t> grid_result;
|
||||
grid_result.resize(GRIDSIZE * GRIDSIZE * GRIDSIZE);
|
||||
|
||||
std::vector<uint8_t> occlusion;
|
||||
occlusion.resize(GRIDSIZE * GRIDSIZE * GRIDSIZE);
|
||||
|
|
@ -1081,24 +1080,42 @@ static void LightGrid(bspdata_t *bspdata)
|
|||
for (int z = z_range.begin(); z < z_range.end(); ++z) {
|
||||
for (int y = y_range.begin(); y < y_range.end(); ++y) {
|
||||
for (int x = x_range.begin(); x < x_range.end(); ++x) {
|
||||
|
||||
qvec3d world_point = grid_mins + (qvec3d{x,y,z} * grid_dist);
|
||||
|
||||
qvec3d color = CalcLightgridAtPoint(&bsp, world_point);
|
||||
lightgrid_samples_t samples = CalcLightgridAtPoint(&bsp, world_point);
|
||||
bool occluded = Light_PointInWorld(&bsp, world_point);
|
||||
|
||||
int sample_index = (GRIDSIZE * GRIDSIZE * z) + (GRIDSIZE * y) + x;
|
||||
|
||||
grid_result[sample_index * 3] = clamp((int)color[0], 0, 255);
|
||||
grid_result[sample_index * 3 + 1] = clamp((int)color[1], 0, 255);
|
||||
grid_result[sample_index * 3 + 2] = clamp((int)color[2], 0, 255);
|
||||
|
||||
grid_result[sample_index] = samples;
|
||||
occlusion[sample_index] = occluded;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// num_styles == 1 is a flag for "all grid points use only style 0"
|
||||
const uint8_t all_style_0 = [&](){
|
||||
for (auto &samples : grid_result) {
|
||||
if (samples.used_styles() != 1)
|
||||
return false;
|
||||
if (samples.samples_by_style[0].style != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
|
||||
// otherwise, it gives the maximum used styles across the map.
|
||||
const uint8_t num_styles = [&](){
|
||||
int result = 0;
|
||||
for (auto &samples : grid_result) {
|
||||
result = max(result, samples.used_styles());
|
||||
}
|
||||
return result;
|
||||
}();
|
||||
|
||||
// FIXME: technically num_styles == 1 could happen if all grid points are style 1 or something
|
||||
|
||||
// non-final, experimental lump
|
||||
std::ostringstream str(std::ios_base::out | std::ios_base::binary);
|
||||
str << endianness<std::endian::little>;
|
||||
|
|
@ -1107,9 +1124,23 @@ static void LightGrid(bspdata_t *bspdata)
|
|||
str <= grid_mins;
|
||||
str <= num_styles;
|
||||
|
||||
// color data 3D array
|
||||
for (uint8_t byte : grid_result) {
|
||||
str <= byte;
|
||||
// if the map only has 1 style, write a more compact form
|
||||
if (num_styles == 1) {
|
||||
// color data 3D array
|
||||
for (const lightgrid_samples_t &samples : grid_result) {
|
||||
str <= samples.samples_by_style[0].round_to_int();
|
||||
}
|
||||
} else {
|
||||
// general case
|
||||
for (const lightgrid_samples_t &samples : grid_result) {
|
||||
str <= static_cast<uint8_t>(samples.used_styles());
|
||||
for (int i = 0; i < samples.used_styles(); ++i) {
|
||||
str <= static_cast<uint8_t>(samples.samples_by_style[i].style);
|
||||
}
|
||||
for (int i = 0; i < samples.used_styles(); ++i) {
|
||||
str <= samples.samples_by_style[i].round_to_int();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// occlusion 3D array
|
||||
|
|
|
|||
|
|
@ -1253,11 +1253,8 @@ static void LightFace_Entity(
|
|||
* Calculates light at a given point from an entity
|
||||
*/
|
||||
static void LightPoint_Entity(
|
||||
const mbsp_t *bsp, raystream_occlusion_t &rs, const light_t *entity, const qvec3d &surfpoint, qvec3d &result)
|
||||
const mbsp_t *bsp, raystream_occlusion_t &rs, const light_t *entity, const qvec3d &surfpoint, lightgrid_samples_t &result)
|
||||
{
|
||||
if (entity->style.value() != 0)
|
||||
return; // not doing style lightgrid for now
|
||||
|
||||
rs.clearPushedRays();
|
||||
|
||||
qvec3d surfpointToLightDir;
|
||||
|
|
@ -1297,7 +1294,7 @@ static void LightPoint_Entity(
|
|||
continue;
|
||||
}
|
||||
|
||||
result += rs.getPushedRayColor(j);
|
||||
result.add(rs.getPushedRayColor(j), entity->style.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1415,11 +1412,8 @@ static void LightFace_Sky(const sun_t *sun, lightsurf_t *lightsurf, lightmapdict
|
|||
}
|
||||
|
||||
static void LightPoint_Sky(
|
||||
const mbsp_t *bsp, raystream_intersection_t &rs, const sun_t *sun, const qvec3d &surfpoint, qvec3d &result)
|
||||
const mbsp_t *bsp, raystream_intersection_t &rs, const sun_t *sun, const qvec3d &surfpoint, lightgrid_samples_t &result)
|
||||
{
|
||||
if (sun->style != 0)
|
||||
return; // not doing style lightgrid for now
|
||||
|
||||
// FIXME: Normalized sun vector should be stored in the sun_t. Also clarify which way the vector points (towards or
|
||||
// away..)
|
||||
// FIXME: Much of this is copied/pasted from LightFace_Entity, should probably be merged
|
||||
|
|
@ -1471,7 +1465,7 @@ static void LightPoint_Sky(
|
|||
continue;
|
||||
}
|
||||
|
||||
result += rs.getPushedRayColor(j);
|
||||
result.add(rs.getPushedRayColor(j), sun->style);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1923,7 +1917,7 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t
|
|||
|
||||
static void // mxd
|
||||
LightPoint_SurfaceLight(const mbsp_t *bsp, raystream_occlusion_t &rs, const std::vector<surfacelight_t> &surface_lights,
|
||||
const vec_t &standard_scale, const vec_t &sky_scale, const float &hotspot_clamp, const qvec3d &surfpoint, qvec3d &result)
|
||||
const vec_t &standard_scale, const vec_t &sky_scale, const float &hotspot_clamp, const qvec3d &surfpoint, lightgrid_samples_t &result)
|
||||
{
|
||||
const settings::worldspawn_keys &cfg = light_options;
|
||||
const float surflight_gate = 0.01f;
|
||||
|
|
@ -1978,7 +1972,7 @@ LightPoint_SurfaceLight(const mbsp_t *bsp, raystream_occlusion_t &rs, const std:
|
|||
|
||||
Q_assert(!std::isnan(indirect[0]));
|
||||
|
||||
result += indirect;
|
||||
result.add(indirect, vpl.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2267,7 +2261,7 @@ inline void LightFace_ScaleAndClamp(lightsurf_t *lightsurf)
|
|||
* Same as above LightFace_ScaleAndClamp, but for lightgrid
|
||||
* TODO: share code with above
|
||||
*/
|
||||
inline void LightPoint_ScaleAndClamp(qvec3d &color)
|
||||
static void LightPoint_ScaleAndClamp(qvec3d &color)
|
||||
{
|
||||
const settings::worldspawn_keys &cfg = light_options;
|
||||
|
||||
|
|
@ -2303,6 +2297,15 @@ inline void LightPoint_ScaleAndClamp(qvec3d &color)
|
|||
}
|
||||
}
|
||||
|
||||
static void LightPoint_ScaleAndClamp(lightgrid_samples_t &result)
|
||||
{
|
||||
for (auto &sample : result.samples_by_style) {
|
||||
if (sample.used) {
|
||||
LightPoint_ScaleAndClamp(sample.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf)
|
||||
{
|
||||
/* Apply gamma, rangescale, and clamp */
|
||||
|
|
@ -3244,7 +3247,56 @@ void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings
|
|||
|
||||
// lightgrid
|
||||
|
||||
qvec3d CalcLightgridAtPoint(const mbsp_t *bsp, const qvec3d &world_point)
|
||||
void lightgrid_samples_t::add(const qvec3d &color, int style)
|
||||
{
|
||||
for (auto &sample : samples_by_style) {
|
||||
if (!sample.used) {
|
||||
// allocate new style
|
||||
sample.used = true;
|
||||
sample.style = style;
|
||||
sample.color = color;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sample.style == style) {
|
||||
// found matching style
|
||||
sample.color += color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// uncommon case: all slots are used, but we didn't find a matching style
|
||||
// drop the style with the lowest brightness
|
||||
|
||||
// FIXME: pick lowest brightness
|
||||
logging::print("out of lightstyles\n");
|
||||
samples_by_style[0].style = style;
|
||||
samples_by_style[0].color = color;
|
||||
}
|
||||
|
||||
qvec3b lightgrid_sample_t::round_to_int() const
|
||||
{
|
||||
return qvec3b{
|
||||
clamp((int)round(color[0]), 0, 255),
|
||||
clamp((int)round(color[1]), 0, 255),
|
||||
clamp((int)round(color[2]), 0, 255)
|
||||
};
|
||||
}
|
||||
|
||||
int lightgrid_samples_t::used_styles() const
|
||||
{
|
||||
int used = 0;
|
||||
for (auto &sample : samples_by_style) {
|
||||
if (sample.used) {
|
||||
used++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return used;
|
||||
}
|
||||
|
||||
lightgrid_samples_t CalcLightgridAtPoint(const mbsp_t *bsp, const qvec3d &world_point)
|
||||
{
|
||||
// TODO: use more than 1 ray for better performance
|
||||
raystream_occlusion_t rs(1);
|
||||
|
|
@ -3252,7 +3304,7 @@ qvec3d CalcLightgridAtPoint(const mbsp_t *bsp, const qvec3d &world_point)
|
|||
|
||||
auto &cfg = light_options;
|
||||
|
||||
qvec3d result {0, 0, 0};
|
||||
lightgrid_samples_t result;
|
||||
|
||||
// from DirectLightFace
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue