ericwa/ericw-tools

-tex_saturation_boost changes texture overall brightness.

Opened this issue · 0 comments

I'm using these tools to rebuild Kingpin (Quake2 engine) maps. I've found that the lighting is much less saturated than the lighting in the original maps.

Kingpin maps heavily rely on surface lights and radiosity, so a fix for this issue is to increase the saturation of those surface lights, and bounced lighting, which is what -tex_saturation_boost is supposed to do. The problem is that the way the saturation is adjusted also drastically changes the overall brightness of textures which messes up other aspects of lighting. The description for the -tex_saturation_boost option says increase texture saturation to match original Q2 tools. Is the current implementation really how the original quake 2 tools worked? I wasn't able to get good results with it.

I was able to get good results by changing the implementation of increase_saturation in imglib.cc like this:

#if 1 // NEW
// add amount argument.
static qvec3b increase_saturation(const qvec3b &color, float amount)
#else
static qvec3b increase_saturation(const qvec3b &color)
#endif
{
    qvec3f color_float = qvec3f(color);
    color_float /= 255.0f;

#if 1 // NEW
    // scale channels around their average intensity.
    float average = (color_float[0] + color_float[1] + color_float[2])/3.0f;
    color_float[0] -= average;
    color_float[1] -= average;
    color_float[2] -= average;
    color_float *= amount;
    color_float[0] += average;
    color_float[1] += average;
    color_float[2] += average;
#else
    // square it to boost saturation
    color_float *= color_float;

    // multiply by 2, then scale back to avoid clipping if needed
    color_float *= 2.0f;

    float max_comp = qv::max(color_float);
    if (max_comp > 1.0f) {
        color_float /= max_comp;
    }
#endif

    qvec3b color_int;
    for (int i = 0; i < 3; ++i) {
        color_int[i] = static_cast<uint8_t>(std::clamp(color_float[i] * 255.0f, 0.0f, 255.0f));
    }
    return color_int;
}

And adjust its usage:

#if 1 // NEW
            tex.averageColor = increase_saturation(tex.averageColor, options.tex_saturation_boost.value());
#else
            tex.averageColor =
                mix(tex.averageColor, increase_saturation(tex.averageColor), options.tex_saturation_boost.value());
#endif

And adjust its max value so it can be set > 1:

#if 1 // NEW
      tex_saturation_boost{this, "tex_saturation_boost", 0.0f, 0.0f, 10.0f, &game_group,
          "increase texture saturation to match original Q2 tools"}
#else
      tex_saturation_boost{this, "tex_saturation_boost", 0.0f, 0.0f, 1.0f, &game_group,
          "increase texture saturation to match original Q2 tools"}
#endif

I think it would be advantageous to change the behavior of -tex_saturation_boost to something like this (or maybe a proper RGB > HSV, adjust > RGB conversion).

If the current behavior is desired, then maybe a new option could be added that more naturally adjusts saturation and preserves color intensity?