From 6f17876e863a25f88ffaf05a26ef0b6da362229a Mon Sep 17 00:00:00 2001 From: MirceaKitsune Date: Tue, 22 Apr 2025 23:37:37 +0300 Subject: [PATCH] Support skybox textures with alpha channel --- doc/lua_api.md | 4 ++-- src/client/game.cpp | 9 ++++----- src/client/sky.cpp | 14 ++++++++------ src/network/clientpackethandler.cpp | 7 ++++--- src/script/lua_api/l_object.cpp | 4 ++-- src/server.cpp | 3 ++- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/doc/lua_api.md b/doc/lua_api.md index 6943dec16..66312d189 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8790,8 +8790,8 @@ child will follow movement and rotation of that bone. Some top and bottom textures expect to be aligned with the north face and will need to be rotated by -90 and 90 degrees, respectively, to fit the eastward orientation. * `clouds`: Boolean for whether clouds appear. (default: `true`) - * `sky_color`: A table used in `"regular"` type only, containing the - following values (alpha is ignored): + * `sky_color`: A table used in `"regular"` and `"skybox"` types only. If used with the later, + the `textures` should have an alpha channel. Contains the following values (alpha is ignored): * `day_sky`: ColorSpec, for the top half of the sky during the day. (default: `#61b5f5`) * `day_horizon`: ColorSpec, for the bottom half of the sky during the day. diff --git a/src/client/game.cpp b/src/client/game.cpp index 08be9c809..8fa2ec48a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2866,11 +2866,10 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) ); } else if (event->set_sky->type == "skybox" && event->set_sky->textures.size() == 6) { - // Disable the dyanmic mesh skybox: - sky->setVisible(false); - // Set fog colors: - sky->setFallbackBgColor(event->set_sky->bgcolor); - // Set sunrise and sunset fog tinting: + // Shows the mesh skybox + sky->setVisible(true); + // Update mesh based skybox colours if applicable. + sky->setSkyColors(event->set_sky->sky_color); sky->setHorizonTint( event->set_sky->fog_sun_tint, event->set_sky->fog_moon_tint, diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 958ffa953..b553f2bb6 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -158,6 +158,7 @@ void Sky::render() const f32 t = 1.0f; const f32 o = 0.0f; + const bool has_tex = m_sky_params.textures.size() == 6; static const u16 indices[6] = {0, 1, 2, 0, 2, 3}; video::S3DVertex vertices[4]; @@ -171,7 +172,7 @@ void Sky::render() return; // Draw the six sided skybox, - if (m_sky_params.textures.size() == 6) { + if (has_tex) { for (u32 j = 5; j < 11; j++) { video::SColor c(255, 255, 255, 255); driver->setMaterial(m_materials[j]); @@ -205,7 +206,8 @@ void Sky::render() } // Draw far cloudy fog thing blended with skycolor - if (m_visible) { + // Disabled when using a textured skybox to prevent clipping + if (m_visible && !has_tex) { driver->setMaterial(m_materials[1]); for (u32 j = 0; j < 4; j++) { vertices[0] = video::S3DVertex(-1, -0.02, -1, 0, 0, 1, m_bgcolor, t, t); @@ -268,9 +270,9 @@ void Sky::render() if (m_moon_params.visible) draw_moon(driver, mooncolor, mooncolor2, wicked_time_of_day); - // Draw far cloudy fog thing below all horizons in front of sun, moon - // and stars. - if (m_visible) { + // Draw far cloudy fog thing below all horizons in front of sun, moon and stars. + // Disabled when using a textured skybox to prevent clipping + if (m_visible && !has_tex) { driver->setMaterial(m_materials[1]); for (u32 j = 0; j < 4; j++) { @@ -881,7 +883,7 @@ void Sky::addTextureToSkybox(const std::string &texture, int material_id, video::ITexture *result = tsrc->getTextureForMesh(texture); m_materials[material_id+5] = baseMaterial(); m_materials[material_id+5].setTexture(0, result); - m_materials[material_id+5].MaterialType = video::EMT_SOLID; + m_materials[material_id+5].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; } float getWickedTimeOfDay(float time_of_day) diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index bb1930d96..777ac0406 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1302,8 +1302,8 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) MoonParams moon = SkyboxDefaults::getMoonDefaults(); StarParams stars = SkyboxDefaults::getStarDefaults(); - // Fix for "regular" skies, as color isn't kept: - if (skybox.type == "regular") { + // Fix for "regular" and "skybox" skies, as color isn't kept: + if (skybox.type == "regular" || skybox.type == "skybox") { skybox.sky_color = SkyboxDefaults::getSkyColorDefaults(); skybox.fog_tint_type = "default"; skybox.fog_moon_tint = video::SColor(255, 255, 255, 255); @@ -1351,7 +1351,8 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) *pkt >> texture; skybox.textures.emplace_back(texture); } - } else if (skybox.type == "regular") { + } + if (skybox.type == "regular" || skybox.type == "skybox") { auto &c = skybox.sky_color; *pkt >> c.day_sky >> c.day_horizon >> c.dawn_sky >> c.dawn_horizon >> c.night_sky >> c.night_horizon >> c.indoors; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 816f42857..ec0eeb3d3 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2140,7 +2140,7 @@ int ObjectRef::l_set_sky(lua_State *L) // Preserve old behavior of the sun, moon and stars // when using the old set_sky call. - if (sky_params.type == "regular") { + if (sky_params.type == "regular" || sky_params.type == "skybox") { sun_params.visible = true; sun_params.sunrise_visible = true; moon_params.visible = true; @@ -2181,7 +2181,7 @@ int ObjectRef::l_set_sky(lua_State *L) static void push_sky_color(lua_State *L, const SkyboxParams ¶ms) { lua_newtable(L); - if (params.type == "regular") { + if (params.type == "regular" || params.type == "skybox") { push_ARGB8(L, params.sky_color.day_sky); lua_setfield(L, -2, "day_sky"); push_ARGB8(L, params.sky_color.day_horizon); diff --git a/src/server.cpp b/src/server.cpp index 4fe2d3c4a..a7535cbe7 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1867,7 +1867,8 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams ¶ms) pkt << (u16) params.textures.size(); for (const std::string &texture : params.textures) pkt << texture; - } else if (params.type == "regular") { + } + if (params.type == "regular" || params.type == "skybox") { auto &c = params.sky_color; pkt << c.day_sky << c.day_horizon << c.dawn_sky << c.dawn_horizon << c.night_sky << c.night_horizon << c.indoors;