mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Clean up texture filtering settings (#13683)
This commit is contained in:
parent
d0ee63c766
commit
72ef90885d
@ -371,35 +371,21 @@ enable_3d_clouds (3D clouds) bool true
|
|||||||
|
|
||||||
[**Filtering and Antialiasing]
|
[**Filtering and Antialiasing]
|
||||||
|
|
||||||
# Use mipmapping to scale textures. May slightly increase performance,
|
# Use mipmaps when scaling textures down. May slightly increase performance,
|
||||||
# especially when using a high resolution texture pack.
|
# especially when using a high resolution texture pack.
|
||||||
# Gamma correct downscaling is not supported.
|
# Gamma-correct downscaling is not supported.
|
||||||
mip_map (Mipmapping) bool false
|
mip_map (Mipmapping) bool false
|
||||||
|
|
||||||
# Use anisotropic filtering when viewing at textures from an angle.
|
# Use bilinear filtering when scaling textures down.
|
||||||
anisotropic_filter (Anisotropic filtering) bool false
|
|
||||||
|
|
||||||
# Use bilinear filtering when scaling textures.
|
|
||||||
bilinear_filter (Bilinear filtering) bool false
|
bilinear_filter (Bilinear filtering) bool false
|
||||||
|
|
||||||
# Use trilinear filtering when scaling textures.
|
# Use trilinear filtering when scaling textures down.
|
||||||
|
# If both bilinear and trilinear filtering are enabled, trilinear filtering
|
||||||
|
# is applied.
|
||||||
trilinear_filter (Trilinear filtering) bool false
|
trilinear_filter (Trilinear filtering) bool false
|
||||||
|
|
||||||
# Filtered textures can blend RGB values with fully-transparent neighbors,
|
# Use anisotropic filtering when looking at textures from an angle.
|
||||||
# which PNG optimizers usually discard, often resulting in dark or
|
anisotropic_filter (Anisotropic filtering) bool false
|
||||||
# light edges to transparent textures. Apply a filter to clean that up
|
|
||||||
# at texture load time. This is automatically enabled if mipmapping is enabled.
|
|
||||||
texture_clean_transparent (Clean transparent textures) bool false
|
|
||||||
|
|
||||||
# When using bilinear/trilinear/anisotropic filters, low-resolution textures
|
|
||||||
# can be blurred, so automatically upscale them with nearest-neighbor
|
|
||||||
# interpolation to preserve crisp pixels. This sets the minimum texture size
|
|
||||||
# for the upscaled textures; higher values look sharper, but require more
|
|
||||||
# memory. Powers of 2 are recommended. This setting is ONLY applied if
|
|
||||||
# bilinear/trilinear/anisotropic filtering is enabled.
|
|
||||||
# This is also used as the base node texture size for world-aligned
|
|
||||||
# texture autoscaling.
|
|
||||||
texture_min_size (Minimum texture size) int 64 1 32768
|
|
||||||
|
|
||||||
# Select the antialiasing method to apply.
|
# Select the antialiasing method to apply.
|
||||||
#
|
#
|
||||||
@ -1831,6 +1817,9 @@ world_aligned_mode (World-aligned textures mode) enum enable disable,enable,forc
|
|||||||
# Warning: This option is EXPERIMENTAL!
|
# Warning: This option is EXPERIMENTAL!
|
||||||
autoscale_mode (Autoscaling mode) enum disable disable,enable,force
|
autoscale_mode (Autoscaling mode) enum disable disable,enable,force
|
||||||
|
|
||||||
|
# The base node texture size used for world-aligned texture autoscaling.
|
||||||
|
texture_min_size (Base texture size) int 64 1 32768
|
||||||
|
|
||||||
# Side length of a cube of map blocks that the client will consider together
|
# Side length of a cube of map blocks that the client will consider together
|
||||||
# when generating meshes.
|
# when generating meshes.
|
||||||
# Larger values increase the utilization of the GPU by reducing the number of
|
# Larger values increase the utilization of the GPU by reducing the number of
|
||||||
|
@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "clientmap.h"
|
#include "clientmap.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "client/mesh.h"
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#include <IMaterialRenderer.h>
|
#include <IMaterialRenderer.h>
|
||||||
#include <matrix4.h>
|
#include <matrix4.h>
|
||||||
@ -843,7 +844,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||||||
|
|
||||||
// Apply filter settings
|
// Apply filter settings
|
||||||
material.forEachTexture([this] (auto &tex) {
|
material.forEachTexture([this] (auto &tex) {
|
||||||
tex.setFiltersMinetest(m_cache_bilinear_filter, m_cache_trilinear_filter,
|
setMaterialFilters(tex, m_cache_bilinear_filter, m_cache_trilinear_filter,
|
||||||
m_cache_anistropic_filter);
|
m_cache_anistropic_filter);
|
||||||
});
|
});
|
||||||
material.Wireframe = m_control.show_wireframe;
|
material.Wireframe = m_control.show_wireframe;
|
||||||
|
@ -1355,7 +1355,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(use_bilinear_filter, use_trilinear_filter,
|
setMaterialFilters(tex, use_bilinear_filter, use_trilinear_filter,
|
||||||
use_anisotropic_filter);
|
use_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1383,15 +1383,8 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
material.Lighting = true;
|
material.Lighting = true;
|
||||||
material.BackfaceCulling = m_prop.backface_culling;
|
material.BackfaceCulling = m_prop.backface_culling;
|
||||||
|
|
||||||
// don't filter low-res textures, makes them look blurry
|
|
||||||
// player models have a res of 64
|
|
||||||
const core::dimension2d<u32> &size = texture->getOriginalSize();
|
|
||||||
const u32 res = std::min(size.Height, size.Width);
|
|
||||||
use_trilinear_filter &= res > 64;
|
|
||||||
use_bilinear_filter &= res > 64;
|
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(use_bilinear_filter, use_trilinear_filter,
|
setMaterialFilters(tex, use_bilinear_filter, use_trilinear_filter,
|
||||||
use_anisotropic_filter);
|
use_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1438,7 +1431,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(use_bilinear_filter, use_trilinear_filter,
|
setMaterialFilters(tex, use_bilinear_filter, use_trilinear_filter,
|
||||||
use_anisotropic_filter);
|
use_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1463,7 +1456,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(use_bilinear_filter, use_trilinear_filter,
|
setMaterialFilters(tex, use_bilinear_filter, use_trilinear_filter,
|
||||||
use_anisotropic_filter);
|
use_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1492,7 +1485,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(use_bilinear_filter, use_trilinear_filter,
|
setMaterialFilters(tex, use_bilinear_filter, use_trilinear_filter,
|
||||||
use_anisotropic_filter);
|
use_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -503,3 +503,18 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
|
|||||||
}
|
}
|
||||||
return dst_mesh;
|
return dst_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMaterialFilters(video::SMaterialLayer &tex, bool bilinear, bool trilinear, bool anisotropic) {
|
||||||
|
if (trilinear)
|
||||||
|
tex.MinFilter = video::ETMINF_LINEAR_MIPMAP_LINEAR;
|
||||||
|
else if (bilinear)
|
||||||
|
tex.MinFilter = video::ETMINF_LINEAR_MIPMAP_NEAREST;
|
||||||
|
else
|
||||||
|
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
||||||
|
|
||||||
|
// "We don't want blurriness after all." ~ Desour, #13108
|
||||||
|
// (because of pixel art)
|
||||||
|
tex.MagFilter = video::ETMAGF_NEAREST;
|
||||||
|
|
||||||
|
tex.AnisotropicFilter = anisotropic ? 0xFF : 0;
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "SMaterialLayer.h"
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
|
|
||||||
@ -133,3 +134,10 @@ void recalculateBoundingBox(scene::IMesh *src_mesh);
|
|||||||
We assume normal to be valid when it's 0 < length < Inf. and not NaN
|
We assume normal to be valid when it's 0 < length < Inf. and not NaN
|
||||||
*/
|
*/
|
||||||
bool checkMeshNormals(scene::IMesh *mesh);
|
bool checkMeshNormals(scene::IMesh *mesh);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the MinFilter, MagFilter and AnisotropicFilter properties of a texture
|
||||||
|
layer according to the three relevant boolean values found in the Minetest
|
||||||
|
settings.
|
||||||
|
*/
|
||||||
|
void setMaterialFilters(video::SMaterialLayer &tex, bool bilinear, bool trilinear, bool anisotropic);
|
||||||
|
@ -433,10 +433,8 @@ private:
|
|||||||
// Maps image file names to loaded palettes.
|
// Maps image file names to loaded palettes.
|
||||||
std::unordered_map<std::string, Palette> m_palettes;
|
std::unordered_map<std::string, Palette> m_palettes;
|
||||||
|
|
||||||
// Cached settings needed for making textures from meshes
|
// Cached settings needed for making textures for meshes
|
||||||
bool m_setting_mipmap;
|
bool m_mesh_texture_prefilter;
|
||||||
bool m_setting_trilinear_filter;
|
|
||||||
bool m_setting_bilinear_filter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableTextureSource *createTextureSource()
|
IWritableTextureSource *createTextureSource()
|
||||||
@ -455,9 +453,9 @@ TextureSource::TextureSource()
|
|||||||
// Cache some settings
|
// Cache some settings
|
||||||
// Note: Since this is only done once, the game must be restarted
|
// Note: Since this is only done once, the game must be restarted
|
||||||
// for these settings to take effect
|
// for these settings to take effect
|
||||||
m_setting_mipmap = g_settings->getBool("mip_map");
|
m_mesh_texture_prefilter =
|
||||||
m_setting_trilinear_filter = g_settings->getBool("trilinear_filter");
|
g_settings->getBool("mip_map") || g_settings->getBool("bilinear_filter") ||
|
||||||
m_setting_bilinear_filter = g_settings->getBool("bilinear_filter");
|
g_settings->getBool("trilinear_filter") || g_settings->getBool("anisotropic_filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureSource::~TextureSource()
|
TextureSource::~TextureSource()
|
||||||
@ -701,12 +699,8 @@ video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id)
|
|||||||
|
|
||||||
video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id)
|
video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id)
|
||||||
{
|
{
|
||||||
static thread_local bool filter_needed =
|
|
||||||
g_settings->getBool("texture_clean_transparent") || m_setting_mipmap ||
|
|
||||||
((m_setting_trilinear_filter || m_setting_bilinear_filter) &&
|
|
||||||
g_settings->getS32("texture_min_size") > 1);
|
|
||||||
// Avoid duplicating texture if it won't actually change
|
// Avoid duplicating texture if it won't actually change
|
||||||
if (filter_needed)
|
if (m_mesh_texture_prefilter)
|
||||||
return getTexture(name + "^[applyfiltersformesh", id);
|
return getTexture(name + "^[applyfiltersformesh", id);
|
||||||
return getTexture(name, id);
|
return getTexture(name, id);
|
||||||
}
|
}
|
||||||
@ -1741,46 +1735,8 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the "clean transparent" filter, if needed
|
// Apply the "clean transparent" filter, if needed
|
||||||
if (m_setting_mipmap || g_settings->getBool("texture_clean_transparent"))
|
if (m_mesh_texture_prefilter)
|
||||||
imageCleanTransparent(baseimg, 127);
|
imageCleanTransparent(baseimg, 127);
|
||||||
|
|
||||||
/* Upscale textures to user's requested minimum size. This is a trick to make
|
|
||||||
* filters look as good on low-res textures as on high-res ones, by making
|
|
||||||
* low-res textures BECOME high-res ones. This is helpful for worlds that
|
|
||||||
* mix high- and low-res textures, or for mods with least-common-denominator
|
|
||||||
* textures that don't have the resources to offer high-res alternatives.
|
|
||||||
*/
|
|
||||||
const bool filter = m_setting_trilinear_filter || m_setting_bilinear_filter;
|
|
||||||
const s32 scaleto = filter ? g_settings->getU16("texture_min_size") : 1;
|
|
||||||
if (scaleto > 1) {
|
|
||||||
const core::dimension2d<u32> dim = baseimg->getDimension();
|
|
||||||
|
|
||||||
/* Calculate scaling needed to make the shortest texture dimension
|
|
||||||
* equal to the target minimum. If e.g. this is a vertical frames
|
|
||||||
* animation, the short dimension will be the real size.
|
|
||||||
*/
|
|
||||||
if ((dim.Width == 0) || (dim.Height == 0)) {
|
|
||||||
errorstream << "generateImagePart(): Illegal 0 dimension "
|
|
||||||
<< "for part_of_name=\""<< part_of_name
|
|
||||||
<< "\", cancelling." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
u32 xscale = scaleto / dim.Width;
|
|
||||||
u32 yscale = scaleto / dim.Height;
|
|
||||||
u32 scale = (xscale > yscale) ? xscale : yscale;
|
|
||||||
|
|
||||||
// Never downscale; only scale up by 2x or more.
|
|
||||||
if (scale > 1) {
|
|
||||||
u32 w = scale * dim.Width;
|
|
||||||
u32 h = scale * dim.Height;
|
|
||||||
const core::dimension2d<u32> newdim = core::dimension2d<u32>(w, h);
|
|
||||||
video::IImage *newimg = driver->createImage(
|
|
||||||
baseimg->getColorFormat(), newdim);
|
|
||||||
baseimg->copyToScaling(newimg);
|
|
||||||
baseimg->drop();
|
|
||||||
baseimg = newimg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
[resize:WxH
|
[resize:WxH
|
||||||
|
@ -297,11 +297,8 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
|
|||||||
material.MaterialType = m_material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
material.BackfaceCulling = true;
|
material.BackfaceCulling = true;
|
||||||
// Enable bi/trilinear filtering only for high resolution textures
|
|
||||||
bool bilinear_filter = dim.Width > 32 && m_bilinear_filter;
|
|
||||||
bool trilinear_filter = dim.Width > 32 && m_trilinear_filter;
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
tex.setFiltersMinetest(bilinear_filter, trilinear_filter,
|
setMaterialFilters(tex, m_bilinear_filter, m_trilinear_filter,
|
||||||
m_anisotropic_filter);
|
m_anisotropic_filter);
|
||||||
});
|
});
|
||||||
// mipmaps cause "thin black line" artifacts
|
// mipmaps cause "thin black line" artifacts
|
||||||
@ -465,7 +462,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
|
|||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
material.BackfaceCulling = cull_backface;
|
material.BackfaceCulling = cull_backface;
|
||||||
material.forEachTexture([this] (auto &tex) {
|
material.forEachTexture([this] (auto &tex) {
|
||||||
tex.setFiltersMinetest(m_bilinear_filter, m_trilinear_filter,
|
setMaterialFilters(tex, m_bilinear_filter, m_trilinear_filter,
|
||||||
m_anisotropic_filter);
|
m_anisotropic_filter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ void set_default_settings()
|
|||||||
settings->setDefault("undersampling", "1");
|
settings->setDefault("undersampling", "1");
|
||||||
settings->setDefault("world_aligned_mode", "enable");
|
settings->setDefault("world_aligned_mode", "enable");
|
||||||
settings->setDefault("autoscale_mode", "disable");
|
settings->setDefault("autoscale_mode", "disable");
|
||||||
|
settings->setDefault("texture_min_size", "64");
|
||||||
settings->setDefault("enable_fog", "true");
|
settings->setDefault("enable_fog", "true");
|
||||||
settings->setDefault("fog_start", "0.4");
|
settings->setDefault("fog_start", "0.4");
|
||||||
settings->setDefault("3d_mode", "none");
|
settings->setDefault("3d_mode", "none");
|
||||||
@ -235,8 +236,6 @@ void set_default_settings()
|
|||||||
settings->setDefault("hud_hotbar_max_width", "1.0");
|
settings->setDefault("hud_hotbar_max_width", "1.0");
|
||||||
settings->setDefault("enable_local_map_saving", "false");
|
settings->setDefault("enable_local_map_saving", "false");
|
||||||
settings->setDefault("show_entity_selectionbox", "false");
|
settings->setDefault("show_entity_selectionbox", "false");
|
||||||
settings->setDefault("texture_clean_transparent", "false");
|
|
||||||
settings->setDefault("texture_min_size", "64");
|
|
||||||
settings->setDefault("ambient_occlusion_gamma", "1.8");
|
settings->setDefault("ambient_occlusion_gamma", "1.8");
|
||||||
settings->setDefault("enable_shaders", "true");
|
settings->setDefault("enable_shaders", "true");
|
||||||
settings->setDefault("enable_particles", "true");
|
settings->setDefault("enable_particles", "true");
|
||||||
@ -252,9 +251,9 @@ void set_default_settings()
|
|||||||
settings->setDefault("directional_colored_fog", "true");
|
settings->setDefault("directional_colored_fog", "true");
|
||||||
settings->setDefault("inventory_items_animations", "false");
|
settings->setDefault("inventory_items_animations", "false");
|
||||||
settings->setDefault("mip_map", "false");
|
settings->setDefault("mip_map", "false");
|
||||||
settings->setDefault("anisotropic_filter", "false");
|
|
||||||
settings->setDefault("bilinear_filter", "false");
|
settings->setDefault("bilinear_filter", "false");
|
||||||
settings->setDefault("trilinear_filter", "false");
|
settings->setDefault("trilinear_filter", "false");
|
||||||
|
settings->setDefault("anisotropic_filter", "false");
|
||||||
settings->setDefault("tone_mapping", "false");
|
settings->setDefault("tone_mapping", "false");
|
||||||
settings->setDefault("enable_waving_water", "false");
|
settings->setDefault("enable_waving_water", "false");
|
||||||
settings->setDefault("water_wave_height", "1.0");
|
settings->setDefault("water_wave_height", "1.0");
|
||||||
|
Loading…
Reference in New Issue
Block a user