Skip to content

Commit 7a1464d

Browse files
authoredNov 26, 2021
Minimap: gamma-correct average texture colour calculation (#9249)
This calculates the average texture colour while heeding the sRGB colourspace.
1 parent 206e131 commit 7a1464d

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed
 

Diff for: ‎src/client/tile.cpp

+46-9
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,48 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
22292229
return NULL;
22302230
}
22312231

2232+
namespace {
2233+
// For more colourspace transformations, see for example
2234+
// https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl
2235+
2236+
inline float linear_to_srgb_component(float v)
2237+
{
2238+
if (v > 0.0031308f)
2239+
return 1.055f * powf(v, 1.0f / 2.4f) - 0.055f;
2240+
return 12.92f * v;
2241+
}
2242+
inline float srgb_to_linear_component(float v)
2243+
{
2244+
if (v > 0.04045f)
2245+
return powf((v + 0.055f) / 1.055f, 2.4f);
2246+
return v / 12.92f;
2247+
}
2248+
2249+
v3f srgb_to_linear(const video::SColor &col_srgb)
2250+
{
2251+
v3f col(col_srgb.getRed(), col_srgb.getGreen(), col_srgb.getBlue());
2252+
col /= 255.0f;
2253+
col.X = srgb_to_linear_component(col.X);
2254+
col.Y = srgb_to_linear_component(col.Y);
2255+
col.Z = srgb_to_linear_component(col.Z);
2256+
return col;
2257+
}
2258+
2259+
video::SColor linear_to_srgb(const v3f &col_linear)
2260+
{
2261+
v3f col;
2262+
col.X = linear_to_srgb_component(col_linear.X);
2263+
col.Y = linear_to_srgb_component(col_linear.Y);
2264+
col.Z = linear_to_srgb_component(col_linear.Z);
2265+
col *= 255.0f;
2266+
col.X = core::clamp<float>(col.X, 0.0f, 255.0f);
2267+
col.Y = core::clamp<float>(col.Y, 0.0f, 255.0f);
2268+
col.Z = core::clamp<float>(col.Z, 0.0f, 255.0f);
2269+
return video::SColor(0xff, myround(col.X), myround(col.Y),
2270+
myround(col.Z));
2271+
}
2272+
}
2273+
22322274
video::SColor TextureSource::getTextureAverageColor(const std::string &name)
22332275
{
22342276
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
@@ -2243,9 +2285,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
22432285
return c;
22442286

22452287
u32 total = 0;
2246-
u32 tR = 0;
2247-
u32 tG = 0;
2248-
u32 tB = 0;
2288+
v3f col_acc(0, 0, 0);
22492289
core::dimension2d<u32> dim = image->getDimension();
22502290
u16 step = 1;
22512291
if (dim.Width > 16)
@@ -2255,17 +2295,14 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
22552295
c = image->getPixel(x,y);
22562296
if (c.getAlpha() > 0) {
22572297
total++;
2258-
tR += c.getRed();
2259-
tG += c.getGreen();
2260-
tB += c.getBlue();
2298+
col_acc += srgb_to_linear(c);
22612299
}
22622300
}
22632301
}
22642302
image->drop();
22652303
if (total > 0) {
2266-
c.setRed(tR / total);
2267-
c.setGreen(tG / total);
2268-
c.setBlue(tB / total);
2304+
col_acc /= total;
2305+
c = linear_to_srgb(col_acc);
22692306
}
22702307
c.setAlpha(255);
22712308
return c;

0 commit comments

Comments
 (0)
Please sign in to comment.