From a73b4f27cb4682df538682f7277424f6b912df64 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 25 May 2024 16:07:35 +0200 Subject: [PATCH 01/15] Make item alpha rendering consistent with their definition --- src/client/hud.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 6bb9c234b..60eabc1f9 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include "EMaterialTypes.h" +#include "itemdef.h" +#include "mapnode.h" #include "settings.h" #include "util/numeric.h" #include "log.h" @@ -1143,7 +1146,23 @@ void drawItemStack( } video::SMaterial &material = buf->getMaterial(); - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 + if (def.type == ITEM_NODE) { + switch (client->ndef()->get(def.name).alpha) { + case ALPHAMODE_OPAQUE: + material.MaterialType = video::EMT_SOLID; + break; + case ALPHAMODE_CLIP: + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material.MaterialTypeParam = 0.5f; + break; + case ALPHAMODE_BLEND: + break; + default: + assert(false); + } + } material.Lighting = false; driver->setMaterial(material); driver->drawMeshBuffer(buf); From 9375f66c487359203d9d651a343fd09589e361c0 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 25 May 2024 16:57:41 +0200 Subject: [PATCH 02/15] Fix rendering of translucent wield meshes --- src/client/wieldmesh.cpp | 34 ++++++++++++++++++++++++++++------ src/client/wieldmesh.h | 1 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 66f89efb1..6a40ce062 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "wieldmesh.h" +#include "SMaterial.h" #include "settings.h" #include "shader.h" #include "inventory.h" @@ -196,7 +197,7 @@ static ExtrusionMeshCache *g_extrusion_mesh_cache = nullptr; WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id, bool lighting): scene::ISceneNode(mgr->getRootSceneNode(), mgr, id), - m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF), + m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL), m_lighting(lighting) { m_enable_shaders = g_settings->getBool("enable_shaders"); @@ -295,7 +296,8 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; material.MaterialType = m_material_type; - material.MaterialTypeParam = 0.5f; + material.MaterialTypeParam = m_material_type_param; + material.ZWriteEnable = video::EZW_ON; material.BackfaceCulling = true; // Enable bi/trilinear filtering only for high resolution textures bool bilinear_filter = dim.Width > 32 && m_bilinear_filter; @@ -361,6 +363,19 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n, return mesh; } +static MaterialType getTileMaterial(AlphaMode alpha) { + switch (alpha) { + case ALPHAMODE_OPAQUE: + return TILE_MATERIAL_OPAQUE; + case ALPHAMODE_CLIP: + return TILE_MATERIAL_BASIC; + case ALPHAMODE_BLEND: + return TILE_MATERIAL_ALPHA; + default: + assert(false); + } +} + void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool check_wield_image) { ITextureSource *tsrc = client->getTextureSource(); @@ -374,8 +389,12 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che scene::SMesh *mesh = nullptr; if (m_enable_shaders) { - u32 shader_id = shdrsrc->getShader("object_shader", TILE_MATERIAL_BASIC, NDT_NORMAL); + const auto tile_mat = def.type == ITEM_NODE ? getTileMaterial(f.alpha) : TILE_MATERIAL_ALPHA; + u32 shader_id = shdrsrc->getShader("object_shader", + tile_mat, def.type == ITEM_NODE ? f.drawtype : NDT_MESH); m_material_type = shdrsrc->getShaderInfo(shader_id).material; + // For translucent items, render everything with alpha > 0 + m_material_type_param = tile_mat == TILE_MATERIAL_ALPHA ? 0.0f : 0.5f; } // Color-related @@ -463,7 +482,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che for (u32 i = 0; i < material_count; ++i) { video::SMaterial &material = m_meshnode->getMaterial(i); material.MaterialType = m_material_type; - material.MaterialTypeParam = 0.5f; + material.MaterialTypeParam = m_material_type_param; + material.ZWriteEnable = video::EZW_ON; material.BackfaceCulling = cull_backface; material.forEachTexture([this] (auto &tex) { setMaterialFilters(tex, m_bilinear_filter, m_trilinear_filter, @@ -665,7 +685,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); video::SMaterial &material = buf->getMaterial(); material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialTypeParam = 0.5f; + material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 + material.ZWriteEnable = video::EZW_ON; material.forEachTexture([] (auto &tex) { tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; tex.MagFilter = video::ETMAGF_NEAREST; @@ -726,7 +747,8 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, material.BackfaceCulling = true; material.Lighting = false; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialTypeParam = 0.5f; + material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 + material.ZWriteEnable = video::EZW_ON; } scaleMesh(mesh, v3f(2.0, 2.0, 2.0)); diff --git a/src/client/wieldmesh.h b/src/client/wieldmesh.h index 6358a6665..954a28465 100644 --- a/src/client/wieldmesh.h +++ b/src/client/wieldmesh.h @@ -118,6 +118,7 @@ class WieldMeshSceneNode : public scene::ISceneNode // Child scene node with the current wield mesh scene::IMeshSceneNode *m_meshnode = nullptr; video::E_MATERIAL_TYPE m_material_type; + f32 m_material_type_param = 0.0f; // True if SMaterial::Lighting should be enabled. bool m_lighting; From 67810800ade63eed84a297b2a989bf0b60b1b619 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 25 May 2024 17:23:07 +0200 Subject: [PATCH 03/15] Register opaque variant of marble --- .../mods/testnodes/performance_test_nodes.lua | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/games/devtest/mods/testnodes/performance_test_nodes.lua b/games/devtest/mods/testnodes/performance_test_nodes.lua index 3eaed614b..ee3c1578c 100644 --- a/games/devtest/mods/testnodes/performance_test_nodes.lua +++ b/games/devtest/mods/testnodes/performance_test_nodes.lua @@ -2,29 +2,22 @@ local S = minetest.get_translator("testnodes") --- Complex mesh -minetest.register_node("testnodes:performance_mesh_clip", { - description = S("Performance Test Node") .. "\n" .. S("Marble with 'clip' transparency"), - drawtype = "mesh", - mesh = "testnodes_marble_glass.obj", - tiles = {"testnodes_marble_glass.png"}, - paramtype = "light", - use_texture_alpha = "clip", +for use_texture_alpha, description in pairs({ + opaque = S("Marble with 'opaque' transparency"), + clip = S("Marble with 'clip' transparency"), + blend = S("Marble with 'blend' transparency"), +}) do + minetest.register_node("testnodes:performance_mesh_" .. use_texture_alpha, { + description = S("Performance Test Node") .. "\n" .. description, + drawtype = "mesh", + mesh = "testnodes_marble_glass.obj", + tiles = {"testnodes_marble_glass.png"}, + paramtype = "light", + use_texture_alpha = use_texture_alpha, - groups = {dig_immediate=3}, -}) - --- Complex mesh, alpha blending -minetest.register_node("testnodes:performance_mesh_blend", { - description = S("Performance Test Node") .. "\n" .. S("Marble with 'blend' transparency"), - drawtype = "mesh", - mesh = "testnodes_marble_glass.obj", - tiles = {"testnodes_marble_glass.png"}, - paramtype = "light", - use_texture_alpha = "blend", - - groups = {dig_immediate=3}, -}) + groups = {dig_immediate=3}, + }) +end -- Overlay minetest.register_node("testnodes:performance_overlay_clip", { From 8c11c12c69fdfd8f001c3ee06aa938bf3f861509 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 1 Jun 2024 17:29:34 +0200 Subject: [PATCH 04/15] Set alpha mode of air to clip --- src/nodedef.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 2914cc3aa..f16dcb9eb 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1082,6 +1082,7 @@ void NodeDefManager::clear() f.name = "air"; f.drawtype = NDT_AIRLIKE; f.param_type = CPT_LIGHT; + f.alpha = ALPHAMODE_CLIP; f.light_propagates = true; f.sunlight_propagates = true; f.walkable = false; From f06364e6a5156183aa626d2cb9a8e23f31fe04c4 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 1 Jun 2024 17:34:49 +0200 Subject: [PATCH 05/15] Fix flowing water def in devtest --- games/devtest/mods/basenodes/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua index 249c7fbd8..50143b9a6 100644 --- a/games/devtest/mods/basenodes/init.lua +++ b/games/devtest/mods/basenodes/init.lua @@ -157,7 +157,7 @@ minetest.register_node("basenodes:water_flowing", { "Drowning damage: 1", drawtype = "flowingliquid", waving = 3, - tiles = {"default_water_flowing.png"}, + tiles = {"default_water_flowing.png"..WATER_ALPHA}, special_tiles = { {name = "default_water_flowing.png"..WATER_ALPHA, backface_culling = false}, From a509aad6b26d06c919a65269800d31b83f0f062b Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 1 Jun 2024 17:49:03 +0200 Subject: [PATCH 06/15] Add translucent test item --- games/devtest/mods/testitems/init.lua | 6 ++++++ .../testitems/textures/testitems_translucent.png | Bin 0 -> 208 bytes 2 files changed, 6 insertions(+) create mode 100644 games/devtest/mods/testitems/textures/testitems_translucent.png diff --git a/games/devtest/mods/testitems/init.lua b/games/devtest/mods/testitems/init.lua index bde9cc6d9..54bbf600e 100644 --- a/games/devtest/mods/testitems/init.lua +++ b/games/devtest/mods/testitems/init.lua @@ -105,3 +105,9 @@ minetest.register_craftitem("testitems:telescope_stick", { return itemstack end, }) + +minetest.register_craftitem("testitems:translucent_item", { + description = S("Translucent item (translucent inventory & wield image)"), + inventory_image = "testitems_translucent.png", + wield_image = "testitems_translucent.png", +}) \ No newline at end of file diff --git a/games/devtest/mods/testitems/textures/testitems_translucent.png b/games/devtest/mods/testitems/textures/testitems_translucent.png new file mode 100644 index 0000000000000000000000000000000000000000..71f8649a6ef276e2a6551ef702b5b49ffccce37a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|x;$MRLoEE0 zQx*sqIDP%Eep$w?h4KH=98aT`k2e$9*x0h98qWUuAJmwTcr5*O;SRocOlxjQ{yV+I ziKoIy+9fHtB~(Ce!~ayRg=||UXEv1RA8A;A^oi64fh-4`ooqR+QV)FBF{&?Qn=v{2 zK#PR85VsKV+h)8D5&PJ%LC{t22WQ%mvv4F FO#nXCONamf literal 0 HcmV?d00001 From ed11b3343053b77d8f43d6b22cf0c8218d71beb5 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 1 Jun 2024 21:18:01 +0200 Subject: [PATCH 07/15] Refactor --- src/client/hud.cpp | 17 ------ src/client/shader.cpp | 21 +------- src/client/tile.cpp | 47 ++++++++++++----- src/client/tile.h | 6 +++ src/client/wieldmesh.cpp | 64 ++++++++++------------ src/client/wieldmesh.h | 1 - src/nodedef.cpp | 111 +++++++++++++++++++++++++++------------ src/nodedef.h | 2 + 8 files changed, 147 insertions(+), 122 deletions(-) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 60eabc1f9..bc8693f3d 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1146,23 +1146,6 @@ void drawItemStack( } video::SMaterial &material = buf->getMaterial(); - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 - if (def.type == ITEM_NODE) { - switch (client->ndef()->get(def.name).alpha) { - case ALPHAMODE_OPAQUE: - material.MaterialType = video::EMT_SOLID; - break; - case ALPHAMODE_CLIP: - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - material.MaterialTypeParam = 0.5f; - break; - case ALPHAMODE_BLEND: - break; - default: - assert(false); - } - } material.Lighting = false; driver->setMaterial(material); driver->drawMeshBuffer(buf); diff --git a/src/client/shader.cpp b/src/client/shader.cpp index dae53ff96..6b9f2698c 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -526,26 +526,7 @@ ShaderInfo ShaderSource::generateShader(const std::string &name, shaderinfo.name = name; shaderinfo.material_type = material_type; shaderinfo.drawtype = drawtype; - switch (material_type) { - case TILE_MATERIAL_OPAQUE: - case TILE_MATERIAL_LIQUID_OPAQUE: - case TILE_MATERIAL_WAVING_LIQUID_OPAQUE: - shaderinfo.base_material = video::EMT_SOLID; - break; - case TILE_MATERIAL_ALPHA: - case TILE_MATERIAL_PLAIN_ALPHA: - case TILE_MATERIAL_LIQUID_TRANSPARENT: - case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: - shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - break; - case TILE_MATERIAL_BASIC: - case TILE_MATERIAL_PLAIN: - case TILE_MATERIAL_WAVING_LEAVES: - case TILE_MATERIAL_WAVING_PLANTS: - case TILE_MATERIAL_WAVING_LIQUID_BASIC: - shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - break; - } + shaderinfo.base_material = MaterialType_to_irr(material_type); shaderinfo.material = shaderinfo.base_material; bool enable_shaders = g_settings->getBool("enable_shaders"); diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 1870547da..3f8db6235 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -18,31 +18,54 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "tile.h" +#include "EMaterialTypes.h" +#include "SMaterial.h" -// Sets everything else except the texture in the material -void TileLayer::applyMaterialOptions(video::SMaterial &material) const +void MaterialType_to_irr(MaterialType material_type, + video::E_MATERIAL_TYPE &irr_mat_type, f32 &irr_mat_param) { switch (material_type) { case TILE_MATERIAL_OPAQUE: case TILE_MATERIAL_LIQUID_OPAQUE: case TILE_MATERIAL_WAVING_LIQUID_OPAQUE: - material.MaterialType = video::EMT_SOLID; + irr_mat_type = video::EMT_SOLID; + irr_mat_param = 0.0f; + break; + case TILE_MATERIAL_ALPHA: + case TILE_MATERIAL_PLAIN_ALPHA: + case TILE_MATERIAL_LIQUID_TRANSPARENT: + case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: + default: + irr_mat_type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + irr_mat_param = 0.0f; break; case TILE_MATERIAL_BASIC: + case TILE_MATERIAL_PLAIN: case TILE_MATERIAL_WAVING_LEAVES: case TILE_MATERIAL_WAVING_PLANTS: case TILE_MATERIAL_WAVING_LIQUID_BASIC: - material.MaterialTypeParam = 0.5; - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - break; - case TILE_MATERIAL_ALPHA: - case TILE_MATERIAL_LIQUID_TRANSPARENT: - case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - break; - default: + irr_mat_type = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + irr_mat_param = 0.5f; break; } +} + +video::E_MATERIAL_TYPE MaterialType_to_irr(MaterialType material_type) { + video::E_MATERIAL_TYPE res; + f32 unused; + MaterialType_to_irr(material_type, res, unused); + return res; +} + +void MaterialType_to_irr(MaterialType material_type, video::SMaterial &material) { + MaterialType_to_irr(material_type, + material.MaterialType, material.MaterialTypeParam); +} + +// Sets everything else except the texture in the material +void TileLayer::applyMaterialOptions(video::SMaterial &material) const +{ + MaterialType_to_irr(static_cast(material_type), material); material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0; if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) { material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; diff --git a/src/client/tile.h b/src/client/tile.h index d761eefdd..ddb0b5fcb 100644 --- a/src/client/tile.h +++ b/src/client/tile.h @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once +#include "EMaterialTypes.h" #include "irrlichttypes.h" #include #include @@ -39,6 +40,11 @@ enum MaterialType{ TILE_MATERIAL_PLAIN_ALPHA }; +void MaterialType_to_irr(MaterialType material_type, + video::E_MATERIAL_TYPE &irr_mat_type, f32 &irr_mat_param); +video::E_MATERIAL_TYPE MaterialType_to_irr(MaterialType material_type); +void MaterialType_to_irr(MaterialType material_type, video::SMaterial &mat); + // Material flags // Should backface culling be enabled? #define MATERIAL_FLAG_BACKFACE_CULLING 0x01 diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 6a40ce062..78aee2c48 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -18,9 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "wieldmesh.h" +#include "EMaterialTypes.h" #include "SMaterial.h" #include "settings.h" -#include "shader.h" #include "inventory.h" #include "client.h" #include "itemdef.h" @@ -249,7 +249,23 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f, scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube(); scene::SMesh *copy = cloneMesh(cubemesh); cubemesh->drop(); - postProcessNodeMesh(copy, f, false, true, &m_material_type, &m_colors, true); + postProcessNodeMesh(copy, f, false, &m_colors, true); + + // Customize materials + for (u32 i = 0; i < cubemesh->getMeshBufferCount(); ++i) { + const TileSpec *tile = &(f.tiles[i]); + scene::IMeshBuffer *buf = cubemesh->getMeshBuffer(i); + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile->layers[layernum]; + if (layer->texture_id == 0) + continue; + video::SMaterial &material = buf->getMaterial(); + layer->applyMaterialOptions(material); + material.MaterialType = m_material_type; + material.MaterialTypeParam = m_material_type_param; + } + } + changeToMesh(copy); copy->drop(); m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR); @@ -357,30 +373,15 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n, buf->append(&p.vertices[0], p.vertices.size(), &p.indices[0], p.indices.size()); buf->drop(); - colors->push_back( - ItemPartColor(p.layer.has_color, p.layer.color)); + colors->emplace_back(p.layer.has_color, p.layer.color); } return mesh; } -static MaterialType getTileMaterial(AlphaMode alpha) { - switch (alpha) { - case ALPHAMODE_OPAQUE: - return TILE_MATERIAL_OPAQUE; - case ALPHAMODE_CLIP: - return TILE_MATERIAL_BASIC; - case ALPHAMODE_BLEND: - return TILE_MATERIAL_ALPHA; - default: - assert(false); - } -} - void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool check_wield_image) { ITextureSource *tsrc = client->getTextureSource(); IItemDefManager *idef = client->getItemDefManager(); - IShaderSource *shdrsrc = client->getShaderSource(); const NodeDefManager *ndef = client->getNodeDefManager(); const ItemDefinition &def = item.getDefinition(idef); const ContentFeatures &f = ndef->get(def.name); @@ -388,14 +389,9 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che scene::SMesh *mesh = nullptr; - if (m_enable_shaders) { - const auto tile_mat = def.type == ITEM_NODE ? getTileMaterial(f.alpha) : TILE_MATERIAL_ALPHA; - u32 shader_id = shdrsrc->getShader("object_shader", - tile_mat, def.type == ITEM_NODE ? f.drawtype : NDT_MESH); - m_material_type = shdrsrc->getShaderInfo(shader_id).material; - // For translucent items, render everything with alpha > 0 - m_material_type_param = tile_mat == TILE_MATERIAL_ALPHA ? 0.0f : 0.5f; - } + const auto material_type = def.type == ITEM_NODE + ? f.getMaterialType() : TILE_MATERIAL_ALPHA; + MaterialType_to_irr(material_type, m_material_type, m_material_type_param); // Color-related m_colors.clear(); @@ -644,8 +640,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) } else scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); // add overlays - postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors, true); + postProcessNodeMesh(mesh, f, false, &result->buffer_colors, true); if (f.drawtype == NDT_ALLFACES) scaleMesh(mesh, v3f(f.visual_scale)); break; @@ -684,8 +679,9 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); video::SMaterial &material = buf->getMaterial(); - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 + const auto material_type = def.type == ITEM_NODE + ? f.getMaterialType() : TILE_MATERIAL_ALPHA; + MaterialType_to_irr(material_type, material); material.ZWriteEnable = video::EZW_ON; material.forEachTexture([] (auto &tex) { tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; @@ -756,8 +752,7 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, } void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, - bool use_shaders, bool set_material, const video::E_MATERIAL_TYPE *mattype, - std::vector *colors, bool apply_scale) + bool use_shaders, std::vector *colors, bool apply_scale) { const u32 mc = mesh->getMeshBufferCount(); // Allocate colors for existing buffers @@ -783,11 +778,6 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, } video::SMaterial &material = buf->getMaterial(); - if (set_material) - layer->applyMaterialOptions(material); - if (mattype) { - material.MaterialType = *mattype; - } if (layer->animation_frame_count > 1) { const FrameSpec &animation_frame = (*layer->frames)[0]; material.setTexture(0, animation_frame.texture); diff --git a/src/client/wieldmesh.h b/src/client/wieldmesh.h index 954a28465..7988c44cc 100644 --- a/src/client/wieldmesh.h +++ b/src/client/wieldmesh.h @@ -159,5 +159,4 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename * \param colors returns the colors of the mesh buffers in the mesh. */ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, bool use_shaders, - bool set_material, const video::E_MATERIAL_TYPE *mattype, std::vector *colors, bool apply_scale = false); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index f16dcb9eb..7ee2ca5dc 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -784,6 +784,80 @@ bool isWorldAligned(AlignStyle style, WorldAlignMode mode, NodeDrawType drawtype return false; } +void ContentFeatures::updateAlpha(bool translucent_liquids) { + if ((drawtype == NDT_LIQUID || drawtype == NDT_FLOWINGLIQUID) && + !translucent_liquids) + alpha = ALPHAMODE_OPAQUE; +} + +MaterialType ContentFeatures::getMaterialType() const +{ + MaterialType material_type; + switch (alpha) { + case ALPHAMODE_OPAQUE: + material_type = TILE_MATERIAL_OPAQUE; + break; + case ALPHAMODE_CLIP: + material_type = TILE_MATERIAL_BASIC; + break; + case ALPHAMODE_BLEND: + default: + material_type = TILE_MATERIAL_ALPHA; + break; + } + switch (drawtype) { + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + switch (alpha) { + case ALPHAMODE_OPAQUE: + return (waving == 3) + ? TILE_MATERIAL_WAVING_LIQUID_OPAQUE + : TILE_MATERIAL_LIQUID_OPAQUE; + case ALPHAMODE_CLIP: + return (waving == 3) + ? TILE_MATERIAL_WAVING_LIQUID_BASIC + : TILE_MATERIAL_LIQUID_TRANSPARENT; + case ALPHAMODE_BLEND: + default: + return (waving == 3) + ? TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT + : TILE_MATERIAL_LIQUID_TRANSPARENT; + } + break; + case NDT_ALLFACES_OPTIONAL: + if (waving >= 1) + return TILE_MATERIAL_WAVING_LEAVES; + break; + case NDT_PLANTLIKE: + if (waving >= 1) + return TILE_MATERIAL_WAVING_PLANTS; + break; + case NDT_MESH: + case NDT_NODEBOX: + switch (waving) { + case 1: + return TILE_MATERIAL_WAVING_PLANTS; + case 2: + return TILE_MATERIAL_WAVING_LEAVES; + case 3: + switch (alpha) { + case ALPHAMODE_OPAQUE: + return TILE_MATERIAL_WAVING_LIQUID_OPAQUE; + case ALPHAMODE_CLIP: + return TILE_MATERIAL_WAVING_LIQUID_BASIC; + case ALPHAMODE_BLEND: + return TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT; + default: + assert(false); + } + break; + } + break; + default: break; + } + return material_type; +} + void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings) { @@ -810,11 +884,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc tdef_spec[j] = tiledef_special[j]; } - bool is_liquid = false; - - MaterialType material_type = alpha == ALPHAMODE_OPAQUE ? - TILE_MATERIAL_OPAQUE : (alpha == ALPHAMODE_CLIP ? TILE_MATERIAL_BASIC : - TILE_MATERIAL_ALPHA); + updateAlpha(tsettings.translucent_liquids); + MaterialType material_type = getMaterialType(); switch (drawtype) { default: @@ -825,16 +896,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc solidness = 0; break; case NDT_LIQUID: - if (!tsettings.translucent_liquids) - alpha = ALPHAMODE_OPAQUE; solidness = 1; - is_liquid = true; break; case NDT_FLOWINGLIQUID: solidness = 0; - if (!tsettings.translucent_liquids) - alpha = ALPHAMODE_OPAQUE; - is_liquid = true; break; case NDT_GLASSLIKE: solidness = 0; @@ -879,13 +944,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc for (TileDef &td : tdef) td.name += std::string("^[noalpha"); } - if (waving >= 1) - material_type = TILE_MATERIAL_WAVING_LEAVES; break; case NDT_PLANTLIKE: solidness = 0; - if (waving >= 1) - material_type = TILE_MATERIAL_WAVING_PLANTS; break; case NDT_FIRELIKE: solidness = 0; @@ -893,15 +954,6 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc case NDT_MESH: case NDT_NODEBOX: solidness = 0; - if (waving == 1) { - material_type = TILE_MATERIAL_WAVING_PLANTS; - } else if (waving == 2) { - material_type = TILE_MATERIAL_WAVING_LEAVES; - } else if (waving == 3) { - material_type = alpha == ALPHAMODE_OPAQUE ? - TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? - TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); - } break; case NDT_TORCHLIKE: case NDT_SIGNLIKE: @@ -914,17 +966,6 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc break; } - if (is_liquid) { - if (waving == 3) { - material_type = alpha == ALPHAMODE_OPAQUE ? - TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? - TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); - } else { - material_type = alpha == ALPHAMODE_OPAQUE ? TILE_MATERIAL_LIQUID_OPAQUE : - TILE_MATERIAL_LIQUID_TRANSPARENT; - } - } - u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype); MaterialType overlay_material = material_type; diff --git a/src/nodedef.h b/src/nodedef.h index de713a1ad..887366103 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -531,6 +531,8 @@ struct ContentFeatures } #ifndef SERVER + void updateAlpha(bool translucent_liquids); + MaterialType getMaterialType() const; void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); #endif From c1a76bc7dbe8d0665b2ac8fd477a367013dbe518 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 16:27:34 +0200 Subject: [PATCH 08/15] Make functions static as appropriate --- src/client/wieldmesh.cpp | 209 ++++++++++++++++++++------------------- src/client/wieldmesh.h | 13 --- 2 files changed, 106 insertions(+), 116 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 78aee2c48..40b63cb57 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock_mesh.h" #include "client/meshgen/collector.h" #include "client/tile.h" -#include "log.h" #include "util/numeric.h" #include #include @@ -42,6 +41,66 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MIN_EXTRUSION_MESH_RESOLUTION 16 #define MAX_EXTRUSION_MESH_RESOLUTION 512 +/*! + * Applies overlays, textures and optionally materials to the given mesh and + * extracts tile colors for colorization. + * \param mattype overrides the buffer's material type, but can also + * be NULL to leave the original material. + * \param colors returns the colors of the mesh buffers in the mesh. + */ +static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, + bool use_shaders, std::vector *colors, bool apply_scale) +{ + const u32 mc = mesh->getMeshBufferCount(); + // Allocate colors for existing buffers + colors->clear(); + colors->resize(mc); + + for (u32 i = 0; i < mc; ++i) { + const TileSpec *tile = &(f.tiles[i]); + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile->layers[layernum]; + if (layer->texture_id == 0) + continue; + if (layernum != 0) { + scene::IMeshBuffer *copy = cloneMeshBuffer(buf); + copy->getMaterial() = buf->getMaterial(); + mesh->addMeshBuffer(copy); + copy->drop(); + buf = copy; + colors->emplace_back(layer->has_color, layer->color); + } else { + (*colors)[i] = ItemPartColor(layer->has_color, layer->color); + } + + video::SMaterial &material = buf->getMaterial(); + if (layer->animation_frame_count > 1) { + const FrameSpec &animation_frame = (*layer->frames)[0]; + material.setTexture(0, animation_frame.texture); + } else { + material.setTexture(0, layer->texture); + } + if (use_shaders) { + if (layer->normal_texture) { + if (layer->animation_frame_count > 1) { + const FrameSpec &animation_frame = (*layer->frames)[0]; + material.setTexture(1, animation_frame.normal_texture); + } else + material.setTexture(1, layer->normal_texture); + } + material.setTexture(2, layer->flags_texture); + } + + if (apply_scale && tile->world_aligned) { + u32 n = buf->getVertexCount(); + for (u32 k = 0; k != n; ++k) + buf->getTCoords(k) /= layer->scale; + } + } + } +} + static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y) { const f32 r = 0.5; @@ -194,6 +253,51 @@ class ExtrusionMeshCache: public IReferenceCounted static ExtrusionMeshCache *g_extrusion_mesh_cache = nullptr; +static scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, + const std::string &imagename, const std::string &overlay_name) +{ + // check textures + video::ITexture *texture = tsrc->getTextureForMesh(imagename); + if (!texture) { + return NULL; + } + video::ITexture *overlay_texture = + (overlay_name.empty()) ? NULL : tsrc->getTexture(overlay_name); + + // get mesh + core::dimension2d dim = texture->getSize(); + scene::IMesh *original = g_extrusion_mesh_cache->create(dim); + scene::SMesh *mesh = cloneMesh(original); + original->drop(); + + //set texture + mesh->getMeshBuffer(0)->getMaterial().setTexture(0, + tsrc->getTexture(imagename)); + if (overlay_texture) { + scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0)); + copy->getMaterial().setTexture(0, overlay_texture); + mesh->addMeshBuffer(copy); + copy->drop(); + } + // Customize materials + for (u32 layer = 0; layer < mesh->getMeshBufferCount(); layer++) { + video::SMaterial &material = mesh->getMeshBuffer(layer)->getMaterial(); + material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.forEachTexture([] (auto &tex) { + tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; + tex.MagFilter = video::ETMAGF_NEAREST; + }); + material.BackfaceCulling = true; + material.Lighting = true; // false; + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 + material.ZWriteEnable = video::EZW_ON; + } + scaleMesh(mesh, v3f(2.0, 2.0, 2.0)); + + return mesh; +} WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id, bool lighting): scene::ISceneNode(mgr->getRootSceneNode(), mgr, id), @@ -701,105 +805,4 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX); } result->mesh = mesh; -} - - - -scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, - const std::string &imagename, const std::string &overlay_name) -{ - // check textures - video::ITexture *texture = tsrc->getTextureForMesh(imagename); - if (!texture) { - return NULL; - } - video::ITexture *overlay_texture = - (overlay_name.empty()) ? NULL : tsrc->getTexture(overlay_name); - - // get mesh - core::dimension2d dim = texture->getSize(); - scene::IMesh *original = g_extrusion_mesh_cache->create(dim); - scene::SMesh *mesh = cloneMesh(original); - original->drop(); - - //set texture - mesh->getMeshBuffer(0)->getMaterial().setTexture(0, - tsrc->getTexture(imagename)); - if (overlay_texture) { - scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0)); - copy->getMaterial().setTexture(0, overlay_texture); - mesh->addMeshBuffer(copy); - copy->drop(); - } - // Customize materials - for (u32 layer = 0; layer < mesh->getMeshBufferCount(); layer++) { - video::SMaterial &material = mesh->getMeshBuffer(layer)->getMaterial(); - material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; - material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; - material.forEachTexture([] (auto &tex) { - tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; - tex.MagFilter = video::ETMAGF_NEAREST; - }); - material.BackfaceCulling = true; - material.Lighting = false; - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 - material.ZWriteEnable = video::EZW_ON; - } - scaleMesh(mesh, v3f(2.0, 2.0, 2.0)); - - return mesh; -} - -void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, - bool use_shaders, std::vector *colors, bool apply_scale) -{ - const u32 mc = mesh->getMeshBufferCount(); - // Allocate colors for existing buffers - colors->clear(); - colors->resize(mc); - - for (u32 i = 0; i < mc; ++i) { - const TileSpec *tile = &(f.tiles[i]); - scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); - for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { - const TileLayer *layer = &tile->layers[layernum]; - if (layer->texture_id == 0) - continue; - if (layernum != 0) { - scene::IMeshBuffer *copy = cloneMeshBuffer(buf); - copy->getMaterial() = buf->getMaterial(); - mesh->addMeshBuffer(copy); - copy->drop(); - buf = copy; - colors->emplace_back(layer->has_color, layer->color); - } else { - (*colors)[i] = ItemPartColor(layer->has_color, layer->color); - } - - video::SMaterial &material = buf->getMaterial(); - if (layer->animation_frame_count > 1) { - const FrameSpec &animation_frame = (*layer->frames)[0]; - material.setTexture(0, animation_frame.texture); - } else { - material.setTexture(0, layer->texture); - } - if (use_shaders) { - if (layer->normal_texture) { - if (layer->animation_frame_count > 1) { - const FrameSpec &animation_frame = (*layer->frames)[0]; - material.setTexture(1, animation_frame.normal_texture); - } else - material.setTexture(1, layer->normal_texture); - } - material.setTexture(2, layer->flags_texture); - } - - if (apply_scale && tile->world_aligned) { - u32 n = buf->getVertexCount(); - for (u32 k = 0; k != n; ++k) - buf->getTCoords(k) /= layer->scale; - } - } - } -} +} \ No newline at end of file diff --git a/src/client/wieldmesh.h b/src/client/wieldmesh.h index 7988c44cc..7e3c8ce4d 100644 --- a/src/client/wieldmesh.h +++ b/src/client/wieldmesh.h @@ -147,16 +147,3 @@ class WieldMeshSceneNode : public scene::ISceneNode }; void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result); - -scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename, - const std::string &overlay_name); - -/*! - * Applies overlays, textures and optionally materials to the given mesh and - * extracts tile colors for colorization. - * \param mattype overrides the buffer's material type, but can also - * be NULL to leave the original material. - * \param colors returns the colors of the mesh buffers in the mesh. - */ -void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, bool use_shaders, - std::vector *colors, bool apply_scale = false); From b3d957127cbe75c64f518711cbf5125c84c5de41 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 16:38:42 +0200 Subject: [PATCH 09/15] Remove always false use_shaders param --- src/client/wieldmesh.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 40b63cb57..c7e4f7500 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -49,7 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc., * \param colors returns the colors of the mesh buffers in the mesh. */ static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, - bool use_shaders, std::vector *colors, bool apply_scale) + std::vector *colors, bool apply_scale) { const u32 mc = mesh->getMeshBufferCount(); // Allocate colors for existing buffers @@ -81,16 +81,6 @@ static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, } else { material.setTexture(0, layer->texture); } - if (use_shaders) { - if (layer->normal_texture) { - if (layer->animation_frame_count > 1) { - const FrameSpec &animation_frame = (*layer->frames)[0]; - material.setTexture(1, animation_frame.normal_texture); - } else - material.setTexture(1, layer->normal_texture); - } - material.setTexture(2, layer->flags_texture); - } if (apply_scale && tile->world_aligned) { u32 n = buf->getVertexCount(); @@ -353,7 +343,7 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f, scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube(); scene::SMesh *copy = cloneMesh(cubemesh); cubemesh->drop(); - postProcessNodeMesh(copy, f, false, &m_colors, true); + postProcessNodeMesh(copy, f, &m_colors, true); // Customize materials for (u32 i = 0; i < cubemesh->getMeshBufferCount(); ++i) { @@ -744,7 +734,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) } else scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); // add overlays - postProcessNodeMesh(mesh, f, false, &result->buffer_colors, true); + postProcessNodeMesh(mesh, f, &result->buffer_colors, true); if (f.drawtype == NDT_ALLFACES) scaleMesh(mesh, v3f(f.visual_scale)); break; From b74c36961bc67aeefdd76c81eae3f4309a562c5c Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 17:01:08 +0200 Subject: [PATCH 10/15] Remove now unused includes --- src/client/hud.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index bc8693f3d..0cfed3d5e 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -23,9 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include "EMaterialTypes.h" -#include "itemdef.h" -#include "mapnode.h" #include "settings.h" #include "util/numeric.h" #include "log.h" From 7f1105cd474c53a13e9dcd393a4c8a74b65d13e3 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 17:16:04 +0200 Subject: [PATCH 11/15] More refactoring --- src/client/wieldmesh.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index c7e4f7500..8ce9fe571 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -49,7 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc., * \param colors returns the colors of the mesh buffers in the mesh. */ static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, - std::vector *colors, bool apply_scale) + std::vector *colors) { const u32 mc = mesh->getMeshBufferCount(); // Allocate colors for existing buffers @@ -82,7 +82,7 @@ static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, material.setTexture(0, layer->texture); } - if (apply_scale && tile->world_aligned) { + if (tile->world_aligned) { u32 n = buf->getVertexCount(); for (u32 k = 0; k != n; ++k) buf->getTCoords(k) /= layer->scale; @@ -279,7 +279,7 @@ static scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, tex.MagFilter = video::ETMAGF_NEAREST; }); material.BackfaceCulling = true; - material.Lighting = true; // false; + material.Lighting = false; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; material.MaterialTypeParam = 0.0f; // render everything with alpha > 0 material.ZWriteEnable = video::EZW_ON; @@ -343,7 +343,7 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f, scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube(); scene::SMesh *copy = cloneMesh(cubemesh); cubemesh->drop(); - postProcessNodeMesh(copy, f, &m_colors, true); + postProcessNodeMesh(copy, f, &m_colors); // Customize materials for (u32 i = 0; i < cubemesh->getMeshBufferCount(); ++i) { @@ -734,7 +734,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) } else scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); // add overlays - postProcessNodeMesh(mesh, f, &result->buffer_colors, true); + postProcessNodeMesh(mesh, f, &result->buffer_colors); if (f.drawtype == NDT_ALLFACES) scaleMesh(mesh, v3f(f.visual_scale)); break; @@ -782,7 +782,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) tex.MagFilter = video::ETMAGF_NEAREST; }); material.BackfaceCulling = cull_backface; - material.Lighting = false; + material.Lighting = false; // no lighting in the inventory } rotateMeshXZby(mesh, -45); From 8b11c73994d46514c8902f8900977ea68eb69fe5 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 17:41:49 +0200 Subject: [PATCH 12/15] Fix items glowing with shaders enabled --- src/client/wieldmesh.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 8ce9fe571..bddf0f624 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -486,6 +486,13 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che const auto material_type = def.type == ITEM_NODE ? f.getMaterialType() : TILE_MATERIAL_ALPHA; MaterialType_to_irr(material_type, m_material_type, m_material_type_param); + if (m_enable_shaders) { + IShaderSource *shdrsrc = client->getShaderSource(); + u32 shader_id = shdrsrc->getShader("object_shader", + material_type, def.type == ITEM_NODE ? f.drawtype : NDT_MESH); + // Note: The shader may give us a different material back. + m_material_type = shdrsrc->getShaderInfo(shader_id).material; + } // Color-related m_colors.clear(); From 34bd7dcde15db3cabd6801d6289287df2c12ee6b Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 18:16:56 +0200 Subject: [PATCH 13/15] Remove unnecessary assignments --- src/client/wieldmesh.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index bddf0f624..29140066a 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -355,8 +355,6 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f, continue; video::SMaterial &material = buf->getMaterial(); layer->applyMaterialOptions(material); - material.MaterialType = m_material_type; - material.MaterialTypeParam = m_material_type_param; } } @@ -462,7 +460,6 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n, } scene::SMeshBuffer *buf = new scene::SMeshBuffer(); buf->Material.setTexture(0, p.layer.texture); - p.layer.applyMaterialOptions(buf->Material); mesh->addMeshBuffer(buf); buf->append(&p.vertices[0], p.vertices.size(), &p.indices[0], p.indices.size()); @@ -780,6 +777,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); video::SMaterial &material = buf->getMaterial(); + // Note: This overwrites material types / type params + // of plantlike extrusion meshes for alpha blending consistency. const auto material_type = def.type == ITEM_NODE ? f.getMaterialType() : TILE_MATERIAL_ALPHA; MaterialType_to_irr(material_type, material); From 1588eab2f7ea8064ca137d468ba54e68629e2ffb Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sun, 2 Jun 2024 18:31:32 +0200 Subject: [PATCH 14/15] More refactoring --- src/client/wieldmesh.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 29140066a..6f46db4d9 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -347,15 +347,11 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f, // Customize materials for (u32 i = 0; i < cubemesh->getMeshBufferCount(); ++i) { - const TileSpec *tile = &(f.tiles[i]); + // It suffices to look at the first layer; + // a special overlay layer needs to be consistent with it - + // otherwise we would be overwriting the material options of the fist layer scene::IMeshBuffer *buf = cubemesh->getMeshBuffer(i); - for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { - const TileLayer *layer = &tile->layers[layernum]; - if (layer->texture_id == 0) - continue; - video::SMaterial &material = buf->getMaterial(); - layer->applyMaterialOptions(material); - } + f.tiles[i].layers[0].applyMaterialOptions(buf->getMaterial()); } changeToMesh(copy); @@ -779,9 +775,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) video::SMaterial &material = buf->getMaterial(); // Note: This overwrites material types / type params // of plantlike extrusion meshes for alpha blending consistency. - const auto material_type = def.type == ITEM_NODE - ? f.getMaterialType() : TILE_MATERIAL_ALPHA; - MaterialType_to_irr(material_type, material); + // It suffices to look at the first layer; overlays need to be consistent. + f.tiles[i].layers[0].applyMaterialOptions(material); material.ZWriteEnable = video::EZW_ON; material.forEachTexture([] (auto &tex) { tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; From 7bf61ed9c73681b90f5ea2e46ec8da99038ccefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Sun, 2 Jun 2024 20:54:13 +0200 Subject: [PATCH 15/15] Explain type vs ID --- src/client/wieldmesh.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 6f46db4d9..5ca794041 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -483,7 +483,9 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che IShaderSource *shdrsrc = client->getShaderSource(); u32 shader_id = shdrsrc->getShader("object_shader", material_type, def.type == ITEM_NODE ? f.drawtype : NDT_MESH); - // Note: The shader may give us a different material back. + // The shader gives a material ID (different from our material type) back. + // Strictly speaking, "m_material type" is a misnomer, + // since either a material type or ID is stored. m_material_type = shdrsrc->getShaderInfo(shader_id).material; } @@ -796,4 +798,4 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX); } result->mesh = mesh; -} \ No newline at end of file +}