Skip to content

Commit 8e7afe6

Browse files
committed
Custom Mip Map generation with SSIM-based perceptual downscaling
Currently, the lower-resolution mip maps in Minetest are generated without gamma correction and are therefore often too dark. Furthermore, common mip maps are downscaled without preserving the image contrast. After this change, it is possible to choose between the default mip map generation and a new custom mip map generation algorithm which preserves image sharpness and average brightness.
1 parent 981d673 commit 8e7afe6

File tree

9 files changed

+463
-10
lines changed

9 files changed

+463
-10
lines changed

builtin/settingtypes.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,18 @@ enable_3d_clouds (3D clouds) bool true
407407
[**Filtering and Antialiasing]
408408

409409
# Use mipmaps when scaling textures. May slightly increase performance,
410-
# especially when using a high-resolution texture pack.
411-
# Gamma-correct downscaling is not supported.
412-
mip_map (Mipmapping) bool false
410+
# especially when using a high-resolution texture pack or a high
411+
# texture_min_size setting. It may also increase join times if textures are
412+
# large.
413+
#
414+
# * off - Disable mipmapping (default)
415+
#
416+
# * simple - Use the default mipmap generation algorithm, which scales
417+
# textures down without gamma-correction
418+
#
419+
# * sharp - Use a custom mipmap generation algorithm, which scales textures
420+
# down while preserving the contrast and average brightness
421+
mip_map (Mipmapping) enum off off,simple,sharp
413422

414423
# Use bilinear filtering when scaling textures.
415424
bilinear_filter (Bilinear filtering) bool false

src/client/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ set(client_SRCS
5555
${CMAKE_CURRENT_SOURCE_DIR}/hud.cpp
5656
${CMAKE_CURRENT_SOURCE_DIR}/imagefilters.cpp
5757
${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
58+
${CMAKE_CURRENT_SOURCE_DIR}/mipmap_generation.cpp
5859
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
5960
${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp
6061
${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp

src/client/game.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,8 @@ bool Game::startup(bool *kill,
11081108
driver = device->getVideoDriver();
11091109
smgr = m_rendering_engine->get_scene_manager();
11101110

1111-
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
1111+
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS,
1112+
g_settings->get("mip_map") != "off");
11121113

11131114
smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
11141115

@@ -1445,7 +1446,7 @@ void Game::copyServerClientCache()
14451446
{
14461447
// It would be possible to let the client directly read the media files
14471448
// from where the server knows they are. But aside from being more complicated
1448-
// it would also *not* fill the media cache and cause slower joining of
1449+
// it would also *not* fill the media cache and cause slower joining of
14491450
// remote servers.
14501451
// (Imagine that you launch a game once locally and then connect to a server.)
14511452

src/client/imagesource.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,7 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
15281528
CHECK_BASEIMG();
15291529

15301530
// Apply the "clean transparent" filter, if needed
1531-
if (m_setting_mipmap || m_setting_bilinear_filter ||
1531+
if (m_setting_mip_map_enabled || m_setting_bilinear_filter ||
15321532
m_setting_trilinear_filter || m_setting_anisotropic_filter)
15331533
imageCleanTransparent(baseimg, 127);
15341534

src/client/imagesource.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct ImageSource {
5959
static video::SColor getImageAverageColor(const video::IImage &image);
6060

6161
ImageSource() :
62-
m_setting_mipmap{g_settings->getBool("mip_map")},
62+
m_setting_mip_map_enabled{g_settings->get("mip_map") != "off"},
6363
m_setting_trilinear_filter{g_settings->getBool("trilinear_filter")},
6464
m_setting_bilinear_filter{g_settings->getBool("bilinear_filter")},
6565
m_setting_anisotropic_filter{g_settings->getBool("anisotropic_filter")}
@@ -74,7 +74,7 @@ struct ImageSource {
7474
std::set<std::string> &source_image_names);
7575

7676
// Cached settings needed for making textures from meshes
77-
bool m_setting_mipmap;
77+
bool m_setting_mip_map_enabled;
7878
bool m_setting_trilinear_filter;
7979
bool m_setting_bilinear_filter;
8080
bool m_setting_anisotropic_filter;

0 commit comments

Comments
 (0)