1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Support drawing the skybox in front of the default sky

This commit is contained in:
MirceaKitsune 2025-04-23 01:28:04 +03:00
parent 6f17876e86
commit d4e0dfa5f6
8 changed files with 62 additions and 35 deletions

View file

@ -8789,6 +8789,9 @@ child will follow movement and rotation of that bone.
bottom texture and the bottom edge of the top texture touch the east face). bottom texture and the bottom edge of the top texture touch the east face).
Some top and bottom textures expect to be aligned with the north face and will need to be rotated 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. by -90 and 90 degrees, respectively, to fit the eastward orientation.
* `textures_front`: Used by the `"skybox"` type. Enable to draw a skybox with an alpha channel in
front of the sun / moon / stars rather than behind them. The sky color will always be shown
behind the alpha channel (default: `false`)
* `clouds`: Boolean for whether clouds appear. (default: `true`) * `clouds`: Boolean for whether clouds appear. (default: `true`)
* `sky_color`: A table used in `"regular"` and `"skybox"` types only. If used with the later, * `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): the `textures` should have an alpha channel. Contains the following values (alpha is ignored):

View file

@ -2850,6 +2850,7 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
sky->setVisible(false); sky->setVisible(false);
// Whether clouds are visible in front of a custom skybox. // Whether clouds are visible in front of a custom skybox.
sky->setCloudsEnabled(event->set_sky->clouds); sky->setCloudsEnabled(event->set_sky->clouds);
sky->setTexturesFront(event->set_sky->textures_front);
// Clear the old textures out in case we switch rendering type. // Clear the old textures out in case we switch rendering type.
sky->clearSkyboxTextures(); sky->clearSkyboxTextures();

View file

@ -93,6 +93,45 @@ void Sky::OnRegisterSceneNode()
scene::ISceneNode::OnRegisterSceneNode(); scene::ISceneNode::OnRegisterSceneNode();
} }
void Sky::renderTextures(video::IVideoDriver *driver)
{
const f32 t = 1.0f;
const f32 o = 0.0f;
static const u16 indices[6] = {0, 1, 2, 0, 2, 3};
video::S3DVertex vertices[4];
for (u32 j = 5; j < 11; j++) {
video::SColor c(255, 255, 255, 255);
driver->setMaterial(m_materials[j]);
// Use 1.05 rather than 1.0 to avoid colliding with the
// sun, moon and stars, as this is a background skybox.
vertices[0] = video::S3DVertex(-1.05, -1.05, -1.05, 0, 0, 1, c, t, t);
vertices[1] = video::S3DVertex( 1.05, -1.05, -1.05, 0, 0, 1, c, o, t);
vertices[2] = video::S3DVertex( 1.05, 1.05, -1.05, 0, 0, 1, c, o, o);
vertices[3] = video::S3DVertex(-1.05, 1.05, -1.05, 0, 0, 1, c, t, o);
for (video::S3DVertex &vertex : vertices) {
if (j == 5) { // Top texture
vertex.Pos.rotateYZBy(90);
vertex.Pos.rotateXZBy(90);
} else if (j == 6) { // Bottom texture
vertex.Pos.rotateYZBy(-90);
vertex.Pos.rotateXZBy(90);
} else if (j == 7) { // Left texture
vertex.Pos.rotateXZBy(90);
} else if (j == 8) { // Right texture
vertex.Pos.rotateXZBy(-90);
} else if (j == 9) { // Front texture, do nothing
// Irrlicht doesn't like it when vertexes are left
// alone and not rotated for some reason.
vertex.Pos.rotateXZBy(0);
} else {// Back texture
vertex.Pos.rotateXZBy(180);
}
}
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
}
}
void Sky::render() void Sky::render()
{ {
video::IVideoDriver *driver = SceneManager->getVideoDriver(); video::IVideoDriver *driver = SceneManager->getVideoDriver();
@ -171,39 +210,9 @@ void Sky::render()
if (m_in_clouds) if (m_in_clouds)
return; return;
// Draw the six sided skybox, // Draw the six sided skybox, in the background.
if (has_tex) { if(has_tex && !m_textures_front)
for (u32 j = 5; j < 11; j++) { renderTextures(driver);
video::SColor c(255, 255, 255, 255);
driver->setMaterial(m_materials[j]);
// Use 1.05 rather than 1.0 to avoid colliding with the
// sun, moon and stars, as this is a background skybox.
vertices[0] = video::S3DVertex(-1.05, -1.05, -1.05, 0, 0, 1, c, t, t);
vertices[1] = video::S3DVertex( 1.05, -1.05, -1.05, 0, 0, 1, c, o, t);
vertices[2] = video::S3DVertex( 1.05, 1.05, -1.05, 0, 0, 1, c, o, o);
vertices[3] = video::S3DVertex(-1.05, 1.05, -1.05, 0, 0, 1, c, t, o);
for (video::S3DVertex &vertex : vertices) {
if (j == 5) { // Top texture
vertex.Pos.rotateYZBy(90);
vertex.Pos.rotateXZBy(90);
} else if (j == 6) { // Bottom texture
vertex.Pos.rotateYZBy(-90);
vertex.Pos.rotateXZBy(90);
} else if (j == 7) { // Left texture
vertex.Pos.rotateXZBy(90);
} else if (j == 8) { // Right texture
vertex.Pos.rotateXZBy(-90);
} else if (j == 9) { // Front texture, do nothing
// Irrlicht doesn't like it when vertexes are left
// alone and not rotated for some reason.
vertex.Pos.rotateXZBy(0);
} else {// Back texture
vertex.Pos.rotateXZBy(180);
}
}
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
}
}
// Draw far cloudy fog thing blended with skycolor // Draw far cloudy fog thing blended with skycolor
// Disabled when using a textured skybox to prevent clipping // Disabled when using a textured skybox to prevent clipping
@ -306,6 +315,10 @@ void Sky::render()
vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o); vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o);
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
} }
// Draw the six sided skybox, in the foreground.
if(has_tex && m_textures_front)
renderTextures(driver);
} }
} }

View file

@ -33,6 +33,7 @@ public:
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
//! renders the node. //! renders the node.
virtual void renderTextures(video::IVideoDriver *driver);
virtual void render(); virtual void render();
virtual const aabb3f &getBoundingBox() const { return m_box; } virtual const aabb3f &getBoundingBox() const { return m_box; }
@ -103,6 +104,7 @@ public:
void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint, void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
const std::string &use_sun_tint); const std::string &use_sun_tint);
void setInClouds(bool clouds) { m_in_clouds = clouds; } void setInClouds(bool clouds) { m_in_clouds = clouds; }
void setTexturesFront(bool textures_front) { m_textures_front = textures_front; }
void clearSkyboxTextures() { m_sky_params.textures.clear(); } void clearSkyboxTextures() { m_sky_params.textures.clear(); }
void addTextureToSkybox(const std::string &texture, int material_id, void addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc); ITextureSource *tsrc);
@ -174,6 +176,7 @@ private:
bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API
bool m_directional_colored_fog; bool m_directional_colored_fog;
bool m_in_clouds = true; // Prevent duplicating bools to remember old values bool m_in_clouds = true; // Prevent duplicating bools to remember old values
bool m_textures_front = false; // Whether textures are rendered behind the default sky
video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);

View file

@ -1295,6 +1295,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
for (size_t i = 0; i < count; i++) for (size_t i = 0; i < count; i++)
skybox.textures.emplace_back(deSerializeString16(is)); skybox.textures.emplace_back(deSerializeString16(is));
skybox.textures_front = false;
skybox.clouds = readU8(is) != 0; skybox.clouds = readU8(is) != 0;
// Use default skybox settings: // Use default skybox settings:
@ -1340,7 +1341,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
SkyboxParams skybox; SkyboxParams skybox;
*pkt >> skybox.bgcolor >> skybox.type >> skybox.clouds >> *pkt >> skybox.bgcolor >> skybox.type >> skybox.textures_front >> skybox.clouds >>
skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type; skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type;
if (skybox.type == "skybox") { if (skybox.type == "skybox") {

View file

@ -2061,6 +2061,7 @@ int ObjectRef::l_set_sky(lua_State *L)
if (sky_params.textures.size() != 6 && !sky_params.textures.empty()) if (sky_params.textures.size() != 6 && !sky_params.textures.empty())
throw LuaError("Skybox expects 6 textures!"); throw LuaError("Skybox expects 6 textures!");
sky_params.textures_front = getboolfield_default(L, 2, "textures_front", sky_params.textures_front);
sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds); sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds);
lua_getfield(L, 2, "sky_color"); lua_getfield(L, 2, "sky_color");
@ -2250,6 +2251,8 @@ int ObjectRef::l_get_sky(lua_State *L)
lua_rawseti(L, -2, i++); lua_rawseti(L, -2, i++);
} }
lua_setfield(L, -2, "textures"); lua_setfield(L, -2, "textures");
lua_pushboolean(L, skybox_params.textures_front);
lua_setfield(L, -2, "textures_front");
lua_pushboolean(L, skybox_params.clouds); lua_pushboolean(L, skybox_params.clouds);
lua_setfield(L, -2, "clouds"); lua_setfield(L, -2, "clouds");

View file

@ -1857,10 +1857,11 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams &params)
for (const std::string& texture : params.textures) for (const std::string& texture : params.textures)
pkt << texture; pkt << texture;
pkt << false;
pkt << params.clouds; pkt << params.clouds;
} else { // Handle current clients and future clients } else { // Handle current clients and future clients
pkt << params.bgcolor << params.type pkt << params.bgcolor << params.type
<< params.clouds << params.fog_sun_tint << params.textures_front << params.clouds << params.fog_sun_tint
<< params.fog_moon_tint << params.fog_tint_type; << params.fog_moon_tint << params.fog_tint_type;
if (params.type == "skybox") { if (params.type == "skybox") {

View file

@ -29,6 +29,7 @@ struct SkyboxParams
video::SColor bgcolor; video::SColor bgcolor;
std::string type; std::string type;
std::vector<std::string> textures; std::vector<std::string> textures;
bool textures_front;
bool clouds; bool clouds;
SkyColor sky_color; SkyColor sky_color;
video::SColor fog_sun_tint; video::SColor fog_sun_tint;
@ -89,6 +90,7 @@ public:
SkyboxParams sky; SkyboxParams sky;
sky.bgcolor = video::SColor(255, 255, 255, 255); sky.bgcolor = video::SColor(255, 255, 255, 255);
sky.type = "regular"; sky.type = "regular";
sky.textures_front = false;
sky.clouds = true; sky.clouds = true;
sky.sky_color = getSkyColorDefaults(); sky.sky_color = getSkyColorDefaults();
sky.fog_sun_tint = video::SColor(255, 244, 125, 29); sky.fog_sun_tint = video::SColor(255, 244, 125, 29);