1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00
This commit is contained in:
Mircea Kitsune 2025-06-26 15:25:01 -07:00 committed by GitHub
commit 9314589cc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 109 additions and 86 deletions

View file

@ -8828,6 +8828,10 @@ child will follow movement and rotation of that bone.
* `type`: Available types: * `type`: Available types:
* `"regular"`: Uses 0 textures, `base_color` ignored * `"regular"`: Uses 0 textures, `base_color` ignored
* `"skybox"`: Uses 6 textures, `base_color` used as fog. * `"skybox"`: Uses 6 textures, `base_color` used as fog.
* `"skybox_back"`: Uses 6 textures, `sky_color` used as fog, stars / sun / moon in foreground.
Note: Requires Luanti client version 5.13 or greater.
* `"skybox_front"`: Uses 6 textures, `sky_color` used as fog, stars / sun / moon in background.
Note: Requires Luanti client version 5.13 or greater.
* `"plain"`: Uses 0 textures, `base_color` used as both fog and sky. * `"plain"`: Uses 0 textures, `base_color` used as both fog and sky.
(default: `"regular"`) (default: `"regular"`)
* `textures`: A table containing up to six textures in the following * `textures`: A table containing up to six textures in the following
@ -8837,8 +8841,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 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.
* `clouds`: Boolean for whether clouds appear. (default: `true`) * `clouds`: Boolean for whether clouds appear. (default: `true`)
* `sky_color`: A table used in `"regular"` type only, containing the * `sky_color`: A table used in `"regular"`, `"skybox_back"`, `"skybox_front"` types only. For a skybox
following values (alpha is ignored): 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. * `day_sky`: ColorSpec, for the top half of the sky during the day.
(default: `#61b5f5`) (default: `#61b5f5`)
* `day_horizon`: ColorSpec, for the bottom half of the sky during the day. * `day_horizon`: ColorSpec, for the bottom half of the sky during the day.

View file

@ -2858,61 +2858,51 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca
void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
{ {
sky->setVisible(false); // Handle invalid sky type.
if (!event->set_sky->isSkybox() && !event->set_sky->isTransparent() && event->set_sky->type != "plain")
infostream << "Unknown sky type: " << (event->set_sky->type) << std::endl;
// Show the mesh sky if transparent.
sky->setVisible(event->set_sky->isTransparent());
sky->setType(event->set_sky->type);
// 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);
// Clear the old textures out in case we switch rendering type. // Show the mesh sky and use skybox colours if transparent.
sky->clearSkyboxTextures(); if (event->set_sky->isTransparent())
// Handle according to type
if (event->set_sky->type == "regular") {
// Shows the mesh skybox
sky->setVisible(true);
// Update mesh based skybox colours if applicable.
sky->setSkyColors(event->set_sky->sky_color); sky->setSkyColors(event->set_sky->sky_color);
else
sky->setFallbackBgColor(event->set_sky->bgcolor);
// Use horizon tint for regular or skybox skies.
if (event->set_sky->isSkybox() || event->set_sky->isTransparent())
sky->setHorizonTint( sky->setHorizonTint(
event->set_sky->fog_sun_tint, event->set_sky->fog_sun_tint,
event->set_sky->fog_moon_tint, event->set_sky->fog_moon_tint,
event->set_sky->fog_tint_type event->set_sky->fog_tint_type
); );
} else if (event->set_sky->type == "skybox" && else
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:
sky->setHorizonTint(
event->set_sky->fog_sun_tint,
event->set_sky->fog_moon_tint,
event->set_sky->fog_tint_type
);
// Add textures to skybox.
for (int i = 0; i < 6; i++)
sky->addTextureToSkybox(event->set_sky->textures[i], i, texture_src);
} else {
// Handle everything else as plain color.
if (event->set_sky->type != "plain")
infostream << "Unknown sky type: "
<< (event->set_sky->type) << std::endl;
sky->setVisible(false);
sky->setFallbackBgColor(event->set_sky->bgcolor);
// Disable directional sun/moon tinting on plain or invalid skyboxes.
sky->setHorizonTint( sky->setHorizonTint(
event->set_sky->bgcolor, event->set_sky->bgcolor,
event->set_sky->bgcolor, event->set_sky->bgcolor,
"custom" "custom"
); );
// Clear the old textures out in case we switch rendering type.
sky->clearSkyboxTextures();
// Add textures to skybox.
if(event->set_sky->isSkybox()) {
for (int i = 0; i < 6; i++)
sky->addTextureToSkybox(event->set_sky->textures[i], i, texture_src, event->set_sky->isTransparent());
} }
// Orbit Tilt: // Orbit Tilt:
sky->setBodyOrbitTilt(event->set_sky->body_orbit_tilt); sky->setBodyOrbitTilt(event->set_sky->body_orbit_tilt);
// fog // Fog, do not override a potentially smaller client setting.
// do not override a potentially smaller client setting.
sky->setFogDistance(event->set_sky->fog_distance); sky->setFogDistance(event->set_sky->fog_distance);
// if the fog distance is reset, switch back to the client's viewing_range // If the fog distance is reset, switch back to the client's viewing_range
if (event->set_sky->fog_distance < 0) if (event->set_sky->fog_distance < 0)
draw_control->wanted_range = g_settings->getS16("viewing_range"); draw_control->wanted_range = g_settings->getS16("viewing_range");

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();
@ -170,42 +209,13 @@ void Sky::render()
if (m_in_clouds) if (m_in_clouds)
return; return;
// Draw the six sided skybox, // Draw the six sided skybox, solid or transparent background.
if (m_sky_params.textures.size() == 6) { if (m_sky_params.type == "skybox" || m_sky_params.type == "skybox_back")
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
if (m_visible) { // Disabled when using a textured skybox to prevent clipping
if (m_visible && !m_sky_params.isSkybox()) {
driver->setMaterial(m_materials[1]); driver->setMaterial(m_materials[1]);
for (u32 j = 0; j < 4; j++) { for (u32 j = 0; j < 4; j++) {
vertices[0] = video::S3DVertex(-1, -0.02, -1, 0, 0, 1, m_bgcolor, t, t); vertices[0] = video::S3DVertex(-1, -0.02, -1, 0, 0, 1, m_bgcolor, t, t);
@ -268,9 +278,9 @@ void Sky::render()
if (m_moon_params.visible) if (m_moon_params.visible)
draw_moon(driver, mooncolor, mooncolor2, wicked_time_of_day); draw_moon(driver, mooncolor, mooncolor2, wicked_time_of_day);
// Draw far cloudy fog thing below all horizons in front of sun, moon // Draw far cloudy fog thing below all horizons in front of sun, moon and stars.
// and stars. // Disabled when using a textured skybox to prevent clipping
if (m_visible) { if (m_visible && !m_sky_params.isSkybox()) {
driver->setMaterial(m_materials[1]); driver->setMaterial(m_materials[1]);
for (u32 j = 0; j < 4; j++) { for (u32 j = 0; j < 4; j++) {
@ -304,6 +314,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, transparent foreground.
if (m_sky_params.type == "skybox_front")
renderTextures(driver);
} }
} }
@ -871,7 +885,7 @@ void Sky::setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
} }
void Sky::addTextureToSkybox(const std::string &texture, int material_id, void Sky::addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc) ITextureSource *tsrc, bool transparent)
{ {
// Sanity check for more than six textures. // Sanity check for more than six textures.
if (material_id + 5 >= SKY_MATERIAL_COUNT) if (material_id + 5 >= SKY_MATERIAL_COUNT)
@ -881,7 +895,7 @@ void Sky::addTextureToSkybox(const std::string &texture, int material_id,
video::ITexture *result = tsrc->getTextureForMesh(texture); video::ITexture *result = tsrc->getTextureForMesh(texture);
m_materials[material_id+5] = baseMaterial(); m_materials[material_id+5] = baseMaterial();
m_materials[material_id+5].setTexture(0, result); m_materials[material_id+5].setTexture(0, result);
m_materials[material_id+5].MaterialType = video::EMT_SOLID; m_materials[material_id+5].MaterialType = transparent ? video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_SOLID;
} }
float getWickedTimeOfDay(float time_of_day) float getWickedTimeOfDay(float time_of_day)

View file

@ -82,6 +82,7 @@ public:
const video::SColorf &getCloudColor() const { return m_cloudcolor_f; } const video::SColorf &getCloudColor() const { return m_cloudcolor_f; }
void setVisible(bool visible) { m_visible = visible; } void setVisible(bool visible) { m_visible = visible; }
void setType(std::string type) { m_sky_params.type = type; }
// Set only from set_sky API // Set only from set_sky API
void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; } void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; }
@ -105,7 +106,7 @@ public:
void setInClouds(bool clouds) { m_in_clouds = clouds; } void setInClouds(bool clouds) { m_in_clouds = clouds; }
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, bool transparent);
// Note: the Sky class doesn't use these values. It just stores them. // Note: the Sky class doesn't use these values. It just stores them.
void setFogDistance(s16 fog_distance) { m_sky_params.fog_distance = fog_distance; } void setFogDistance(s16 fog_distance) { m_sky_params.fog_distance = fog_distance; }
@ -124,6 +125,8 @@ public:
private: private:
aabb3f m_box{{0.0f, 0.0f, 0.0f}}; aabb3f m_box{{0.0f, 0.0f, 0.0f}};
video::SMaterial m_materials[SKY_MATERIAL_COUNT]; video::SMaterial m_materials[SKY_MATERIAL_COUNT];
virtual void renderTextures(video::IVideoDriver *driver);
// How much sun & moon transition should affect horizon color // How much sun & moon transition should affect horizon color
float m_horizon_blend() float m_horizon_blend()
{ {

View file

@ -1303,8 +1303,8 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
MoonParams moon = SkyboxDefaults::getMoonDefaults(); MoonParams moon = SkyboxDefaults::getMoonDefaults();
StarParams stars = SkyboxDefaults::getStarDefaults(); StarParams stars = SkyboxDefaults::getStarDefaults();
// Fix for "regular" skies, as color isn't kept: // Fix for "regular", "skybox_back", "skybox_front" skies as color isn't kept:
if (skybox.type == "regular") { if (skybox.isTransparent()) {
skybox.sky_color = SkyboxDefaults::getSkyColorDefaults(); skybox.sky_color = SkyboxDefaults::getSkyColorDefaults();
skybox.fog_tint_type = "default"; skybox.fog_tint_type = "default";
skybox.fog_moon_tint = video::SColor(255, 255, 255, 255); skybox.fog_moon_tint = video::SColor(255, 255, 255, 255);
@ -1344,7 +1344,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
*pkt >> skybox.bgcolor >> skybox.type >> skybox.clouds >> *pkt >> skybox.bgcolor >> skybox.type >> 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.isSkybox()) {
u16 texture_count; u16 texture_count;
std::string texture; std::string texture;
*pkt >> texture_count; *pkt >> texture_count;
@ -1352,7 +1352,8 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
*pkt >> texture; *pkt >> texture;
skybox.textures.emplace_back(texture); skybox.textures.emplace_back(texture);
} }
} else if (skybox.type == "regular") { }
if (skybox.isTransparent()) {
auto &c = skybox.sky_color; auto &c = skybox.sky_color;
*pkt >> c.day_sky >> c.day_horizon >> c.dawn_sky >> c.dawn_horizon *pkt >> c.day_sky >> c.day_horizon >> c.dawn_sky >> c.dawn_horizon
>> c.night_sky >> c.night_horizon >> c.indoors; >> c.night_sky >> c.night_horizon >> c.indoors;

View file

@ -2067,7 +2067,7 @@ int ObjectRef::l_set_sky(lua_State *L)
lua_getfield(L, 2, "textures"); lua_getfield(L, 2, "textures");
sky_params.textures.clear(); sky_params.textures.clear();
if (lua_istable(L, -1) && sky_params.type == "skybox") { if (lua_istable(L, -1) && sky_params.isSkybox()) {
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, -2) != 0) { while (lua_next(L, -2) != 0) {
// Key is at index -2 and value at index -1 // Key is at index -2 and value at index -1
@ -2161,7 +2161,7 @@ int ObjectRef::l_set_sky(lua_State *L)
// Preserve old behavior of the sun, moon and stars // Preserve old behavior of the sun, moon and stars
// when using the old set_sky call. // when using the old set_sky call.
if (sky_params.type == "regular") { if (sky_params.isTransparent()) {
sun_params.visible = true; sun_params.visible = true;
sun_params.sunrise_visible = true; sun_params.sunrise_visible = true;
moon_params.visible = true; moon_params.visible = true;
@ -2183,7 +2183,7 @@ int ObjectRef::l_set_sky(lua_State *L)
lua_pop(L, 1); lua_pop(L, 1);
} }
} }
if (sky_params.type == "skybox" && sky_params.textures.size() != 6) if (sky_params.isSkybox() && sky_params.textures.size() != 6)
throw LuaError("Skybox expects 6 textures."); throw LuaError("Skybox expects 6 textures.");
sky_params.clouds = true; sky_params.clouds = true;
@ -2202,7 +2202,7 @@ int ObjectRef::l_set_sky(lua_State *L)
static void push_sky_color(lua_State *L, const SkyboxParams &params) static void push_sky_color(lua_State *L, const SkyboxParams &params)
{ {
lua_newtable(L); lua_newtable(L);
if (params.type == "regular") { if (params.isTransparent()) {
push_ARGB8(L, params.sky_color.day_sky); push_ARGB8(L, params.sky_color.day_sky);
lua_setfield(L, -2, "day_sky"); lua_setfield(L, -2, "day_sky");
push_ARGB8(L, params.sky_color.day_horizon); push_ARGB8(L, params.sky_color.day_horizon);

View file

@ -1868,11 +1868,12 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams &params)
<< params.clouds << params.fog_sun_tint << 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.isSkybox()) {
pkt << (u16) params.textures.size(); pkt << (u16) params.textures.size();
for (const std::string &texture : params.textures) for (const std::string &texture : params.textures)
pkt << texture; pkt << texture;
} else if (params.type == "regular") { }
if (params.isTransparent()) {
auto &c = params.sky_color; auto &c = params.sky_color;
pkt << c.day_sky << c.day_horizon << c.dawn_sky << c.dawn_horizon pkt << c.day_sky << c.day_horizon << c.dawn_sky << c.dawn_horizon
<< c.night_sky << c.night_horizon << c.indoors; << c.night_sky << c.night_horizon << c.indoors;

View file

@ -38,6 +38,16 @@ struct SkyboxParams
s16 fog_distance { -1 }; s16 fog_distance { -1 };
float fog_start { -1.0f }; float fog_start { -1.0f };
video::SColor fog_color { 0 }; // override, only used if alpha > 0 video::SColor fog_color { 0 }; // override, only used if alpha > 0
// Check if this is a textured skybox and whether transparency is used
bool isSkybox() const
{
return type == "skybox" || type == "skybox_back" || type == "skybox_front";
}
bool isTransparent() const
{
return type == "regular" || type == "skybox_back" || type == "skybox_front";
}
}; };
struct SunParams struct SunParams