From 7c0e8f9b2479ca166adf8346f0526cd495c7f17c Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 14 Feb 2017 01:09:07 -0700 Subject: [PATCH] light: fix -extra4 downsampling to use occlusion values --- light/ltface.cc | 65 +++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/light/ltface.cc b/light/ltface.cc index 41031c15..bf6b8718 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -2153,36 +2153,38 @@ DumpDownscaledLightmap(const bsp2_t *bsp, const bsp2_dface_t *face, int w, int h WritePPM(std::string{fname}, w, h, rgbdata.data()); } -static std::vector +static std::vector LightmapColorsToGLMVector(const lightsurf_t *lightsurf, const lightmap_t *lm) { - std::vector res; + std::vector res; for (int i=0; inumpoints; i++) { const vec_t *color = lm->samples[i].color; - res.push_back(glm::vec3(color[0], color[1], color[2])); + const float alpha = lightsurf->occluded[i] ? 0.0f : 1.0f; + res.push_back(glm::vec4(color[0], color[1], color[2], alpha)); } return res; } -static std::vector +static std::vector LightmapNormalsToGLMVector(const lightsurf_t *lightsurf, const lightmap_t *lm) { - std::vector res; + std::vector res; for (int i=0; inumpoints; i++) { const vec_t *color = lm->samples[i].direction; - res.push_back(glm::vec3(color[0], color[1], color[2])); + const float alpha = lightsurf->occluded[i] ? 0.0f : 1.0f; + res.push_back(glm::vec4(color[0], color[1], color[2], alpha)); } return res; } -static std::vector +static std::vector LightmapToGLMVector(const bsp2_t *bsp, const lightsurf_t *lightsurf) { const lightmap_t *lm = Lightmap_ForStyle_ReadOnly(lightsurf, 0); if (lm != nullptr) { return LightmapColorsToGLMVector(lightsurf, lm); } - return std::vector(); + return std::vector(); } static glm::vec3 @@ -2207,8 +2209,10 @@ void GLMVector_LinearToGamma(std::vector &vec) { } } -static std::vector -IntegerDownsampleImage(const std::vector &input, int w, int h, int factor) +// Special handling of alpha channel: +// alpha channel is expected to be 0 or 1, 0 = never take samples from this pixel +static std::vector +IntegerDownsampleImage(const std::vector &input, int w, int h, int factor) { Q_assert(factor >= 1); if (factor == 1) @@ -2217,7 +2221,7 @@ IntegerDownsampleImage(const std::vector &input, int w, int h, int fa int outw = w/factor; int outh = h/factor; - std::vector res(static_cast(outw * outh)); + std::vector res(static_cast(outw * outh)); for (int y=0; y &input, int w, int h, int fa continue; if (y1 < 0 || y1 >= h) continue; - + // read the input sample - const glm::vec3 inSample = input.at((y1 * w) + x1); + const glm::vec4 inSample = input.at((y1 * w) + x1); + + if (inSample.a == 0.0f) + continue; const float kernelextent_float = kernelextent + 1.0f; const float x_in_kernel_float = x0 + 0.5f; @@ -2250,15 +2257,19 @@ IntegerDownsampleImage(const std::vector &input, int w, int h, int fa Q_assert(y_in_kernel_float >= 0 && y_in_kernel_float <= kernelextent_float); const float weight = 1.0f; - totalColor += weight * inSample; + totalColor += weight * glm::vec3(inSample); totalWeight += weight; } } - totalColor /= totalWeight; - - res[(y * outw) + x] = totalColor; + const int outIndex = (y * outw) + x; + if (totalWeight > 0.0f) { + const vec4 resultColor = glm::vec4(totalColor / totalWeight, 1.0f); + res[outIndex] = resultColor; + } else { + res[outIndex] = glm::vec4(0.0f); + } } } @@ -2362,20 +2373,20 @@ WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const // allocate new float buffers for the output colors and directions // these are the actual output width*height, without oversampling. - std::vector output_color = IntegerDownsampleImage(LightmapColorsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); - std::vector output_dir = IntegerDownsampleImage(LightmapNormalsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); + const std::vector output_color = IntegerDownsampleImage(LightmapColorsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); + const std::vector output_dir = IntegerDownsampleImage(LightmapNormalsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); // copy from the float buffers to byte buffers in .bsp / .lit / .lux for (int t = 0; t < actual_height; t++) { for (int s = 0; s < actual_width; s++) { const int sampleindex = (t * actual_width) + s; - const glm::vec3 &color = output_color.at(sampleindex); - const glm::vec3 &direction = output_dir.at(sampleindex); + const glm::vec4 &color = output_color.at(sampleindex); + const glm::vec4 &direction = output_dir.at(sampleindex); - *lit++ = color[0]; - *lit++ = color[1]; - *lit++ = color[2]; + *lit++ = color.r; + *lit++ = color.g; + *lit++ = color.b; /* Average the color to get the value to write to the .bsp lightmap. this avoids issues with some engines @@ -2390,9 +2401,9 @@ WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const if (lux) { vec3_t temp; int v; - temp[0] = glm::dot(direction, vec3_t_to_glm(lightsurf->snormal)); - temp[1] = glm::dot(direction, vec3_t_to_glm(lightsurf->tnormal)); - temp[2] = glm::dot(direction, vec3_t_to_glm(lightsurf->plane.normal)); + temp[0] = glm::dot(glm::vec3(direction), vec3_t_to_glm(lightsurf->snormal)); + temp[1] = glm::dot(glm::vec3(direction), vec3_t_to_glm(lightsurf->tnormal)); + temp[2] = glm::dot(glm::vec3(direction), vec3_t_to_glm(lightsurf->plane.normal)); if (!temp[0] && !temp[1] && !temp[2]) VectorSet(temp, 0, 0, 1);