mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
Visual Effects Vol. 1 (#14610)
This PR adds a variety of effects to enhance the visual experience. "soft" clouds look Tinted shadows Crude water reflections (sky and sun) and waves Translucent foliage Node specular highlights Adjusted fog color (more saturated where the fog is lighter) Minor changes to volumetric lighting (crudely simulates the effect of depth) Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
4ac86db8e3
commit
d8f1daac25
24 changed files with 356 additions and 53 deletions
|
@ -137,6 +137,7 @@ struct ClientEvent
|
|||
f32 density;
|
||||
u32 color_bright;
|
||||
u32 color_ambient;
|
||||
u32 color_shadow;
|
||||
f32 height;
|
||||
f32 thickness;
|
||||
f32 speed_x;
|
||||
|
|
|
@ -1209,11 +1209,22 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
|||
// Render all mesh buffers in order
|
||||
drawcall_count += draw_order.size();
|
||||
|
||||
bool translucent_foliage = g_settings->getBool("enable_translucent_foliage");
|
||||
|
||||
video::E_MATERIAL_TYPE leaves_material = video::EMT_SOLID;
|
||||
|
||||
// For translucent leaves, we want to use backface culling instead of frontface.
|
||||
if (translucent_foliage) {
|
||||
// this is the material leaves would use, compare to nodedef.cpp
|
||||
auto* shdsrc = m_client->getShaderSource();
|
||||
const u32 leaves_shader = shdsrc->getShader("nodes_shader", TILE_MATERIAL_WAVING_LEAVES, NDT_ALLFACES);
|
||||
leaves_material = shdsrc->getShaderInfo(leaves_shader).material;
|
||||
}
|
||||
|
||||
for (auto &descriptor : draw_order) {
|
||||
if (!descriptor.m_reuse_material) {
|
||||
// override some material properties
|
||||
video::SMaterial local_material = descriptor.getMaterial();
|
||||
local_material.MaterialType = material.MaterialType;
|
||||
// do not override culling if the original material renders both back
|
||||
// and front faces in solid mode (e.g. plantlike)
|
||||
// Transparent plants would still render shadows only from one side,
|
||||
|
@ -1222,6 +1233,11 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
|||
local_material.BackfaceCulling = material.BackfaceCulling;
|
||||
local_material.FrontfaceCulling = material.FrontfaceCulling;
|
||||
}
|
||||
if (local_material.MaterialType == leaves_material && translucent_foliage) {
|
||||
local_material.BackfaceCulling = true;
|
||||
local_material.FrontfaceCulling = false;
|
||||
}
|
||||
local_material.MaterialType = material.MaterialType;
|
||||
local_material.BlendOperation = material.BlendOperation;
|
||||
driver->setMaterial(local_material);
|
||||
++material_swaps;
|
||||
|
|
|
@ -65,6 +65,8 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
|||
readSettings();
|
||||
g_settings->registerChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
g_settings->registerChangedCallback("soft_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
|
||||
updateBox();
|
||||
|
||||
|
@ -76,6 +78,8 @@ Clouds::~Clouds()
|
|||
{
|
||||
g_settings->deregisterChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
g_settings->deregisterChangedCallback("soft_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
}
|
||||
|
||||
void Clouds::OnRegisterSceneNode()
|
||||
|
@ -141,15 +145,18 @@ void Clouds::updateMesh()
|
|||
// shader mixes the base color, set via ColorParam
|
||||
c_top_f = c_side_1_f = c_side_2_f = c_bottom_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
c_side_1_f.r *= 0.95f;
|
||||
c_side_1_f.g *= 0.95f;
|
||||
c_side_1_f.b *= 0.95f;
|
||||
c_side_2_f.r *= 0.90f;
|
||||
c_side_2_f.g *= 0.90f;
|
||||
c_side_2_f.b *= 0.90f;
|
||||
c_bottom_f.r *= 0.80f;
|
||||
c_bottom_f.g *= 0.80f;
|
||||
c_bottom_f.b *= 0.80f;
|
||||
video::SColorf shadow = m_params.color_shadow;
|
||||
|
||||
c_side_1_f.r *= shadow.r * 0.25f + 0.75f;
|
||||
c_side_1_f.g *= shadow.g * 0.25f + 0.75f;
|
||||
c_side_1_f.b *= shadow.b * 0.25f + 0.75f;
|
||||
c_side_2_f.r *= shadow.r * 0.5f + 0.5f;
|
||||
c_side_2_f.g *= shadow.g * 0.5f + 0.5f;
|
||||
c_side_2_f.b *= shadow.b * 0.5f + 0.5f;
|
||||
c_bottom_f.r *= shadow.r;
|
||||
c_bottom_f.g *= shadow.g;
|
||||
c_bottom_f.b *= shadow.b;
|
||||
|
||||
video::SColor c_top = c_top_f.toSColor();
|
||||
video::SColor c_side_1 = c_side_1_f.toSColor();
|
||||
video::SColor c_side_2 = c_side_2_f.toSColor();
|
||||
|
@ -221,13 +228,14 @@ void Clouds::updateMesh()
|
|||
const f32 ry = is3D() ? m_params.thickness * BS : 0.0f;
|
||||
const f32 rz = cloud_size / 2;
|
||||
|
||||
for(u32 i = 0; i < num_faces_to_draw; i++)
|
||||
bool soft_clouds_enabled = g_settings->getBool("soft_clouds");
|
||||
for (u32 i = 0; i < num_faces_to_draw; i++)
|
||||
{
|
||||
switch(i)
|
||||
switch (i)
|
||||
{
|
||||
case 0: // top
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Normal.set(0,1,0);
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Normal.set(0, 1, 0);
|
||||
}
|
||||
v[0].Pos.set(-rx, ry,-rz);
|
||||
v[1].Pos.set(-rx, ry, rz);
|
||||
|
@ -237,12 +245,20 @@ void Clouds::updateMesh()
|
|||
case 1: // back
|
||||
if (INAREA(xi, zi - 1, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i);
|
||||
if(grid[j])
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0,0,-1);
|
||||
if (soft_clouds_enabled) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Normal.set(0, 0, -1);
|
||||
}
|
||||
v[2].Color = c_bottom;
|
||||
v[3].Color = c_bottom;
|
||||
} else {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0, 0, -1);
|
||||
}
|
||||
}
|
||||
v[0].Pos.set(-rx, ry,-rz);
|
||||
v[1].Pos.set( rx, ry,-rz);
|
||||
|
@ -251,28 +267,45 @@ void Clouds::updateMesh()
|
|||
break;
|
||||
case 2: //right
|
||||
if (INAREA(xi + 1, zi, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi+1, zi, m_cloud_radius_i);
|
||||
if(grid[j])
|
||||
u32 j = GETINDEX(xi + 1, zi, m_cloud_radius_i);
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(1,0,0);
|
||||
if (soft_clouds_enabled) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Normal.set(1, 0, 0);
|
||||
}
|
||||
v[2].Color = c_bottom;
|
||||
v[3].Color = c_bottom;
|
||||
}
|
||||
v[0].Pos.set( rx, ry,-rz);
|
||||
v[1].Pos.set( rx, ry, rz);
|
||||
v[2].Pos.set( rx, 0, rz);
|
||||
v[3].Pos.set( rx, 0,-rz);
|
||||
else {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(1, 0, 0);
|
||||
}
|
||||
}
|
||||
v[0].Pos.set(rx, ry,-rz);
|
||||
v[1].Pos.set(rx, ry, rz);
|
||||
v[2].Pos.set(rx, 0, rz);
|
||||
v[3].Pos.set(rx, 0,-rz);
|
||||
break;
|
||||
case 3: // front
|
||||
if (INAREA(xi, zi + 1, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i);
|
||||
if(grid[j])
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0,0,-1);
|
||||
if (soft_clouds_enabled) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Normal.set(0, 0, -1);
|
||||
}
|
||||
v[2].Color = c_bottom;
|
||||
v[3].Color = c_bottom;
|
||||
} else {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0, 0, -1);
|
||||
}
|
||||
}
|
||||
v[0].Pos.set( rx, ry, rz);
|
||||
v[1].Pos.set(-rx, ry, rz);
|
||||
|
@ -280,14 +313,22 @@ void Clouds::updateMesh()
|
|||
v[3].Pos.set( rx, 0, rz);
|
||||
break;
|
||||
case 4: // left
|
||||
if (INAREA(xi-1, zi, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi-1, zi, m_cloud_radius_i);
|
||||
if(grid[j])
|
||||
if (INAREA(xi - 1, zi, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi - 1, zi, m_cloud_radius_i);
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(-1,0,0);
|
||||
if (soft_clouds_enabled) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Normal.set(-1, 0, 0);
|
||||
}
|
||||
v[2].Color = c_bottom;
|
||||
v[3].Color = c_bottom;
|
||||
} else {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(-1, 0, 0);
|
||||
}
|
||||
}
|
||||
v[0].Pos.set(-rx, ry, rz);
|
||||
v[1].Pos.set(-rx, ry,-rz);
|
||||
|
@ -295,9 +336,9 @@ void Clouds::updateMesh()
|
|||
v[3].Pos.set(-rx, 0, rz);
|
||||
break;
|
||||
case 5: // bottom
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_bottom;
|
||||
vertex.Normal.set(0,-1,0);
|
||||
vertex.Normal.set(0, -1, 0);
|
||||
}
|
||||
v[0].Pos.set( rx, 0, rz);
|
||||
v[1].Pos.set(-rx, 0, rz);
|
||||
|
|
|
@ -109,6 +109,14 @@ public:
|
|||
m_params.color_ambient = color_ambient;
|
||||
}
|
||||
|
||||
void setColorShadow(video::SColor color_shadow)
|
||||
{
|
||||
if (m_params.color_shadow == color_shadow)
|
||||
return;
|
||||
m_params.color_shadow = color_shadow;
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
void setHeight(float height)
|
||||
{
|
||||
if (m_params.height == height)
|
||||
|
|
|
@ -83,7 +83,8 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
|
|||
meshmanip(mm),
|
||||
blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE),
|
||||
enable_mesh_cache(g_settings->getBool("enable_mesh_cache") &&
|
||||
!data->m_smooth_lighting) // Mesh cache is not supported with smooth lighting
|
||||
!data->m_smooth_lighting), // Mesh cache is not supported with smooth lighting
|
||||
smooth_liquids(g_settings->getBool("enable_water_reflections"))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -717,7 +718,7 @@ void MapblockMeshGenerator::drawLiquidSides()
|
|||
if (data->m_smooth_lighting)
|
||||
cur_node.color = blendLightColor(pos);
|
||||
pos += cur_node.origin;
|
||||
vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, 0, 0, 0, cur_node.color, vertex.u, v);
|
||||
vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, face.dir.X, face.dir.Y, face.dir.Z, cur_node.color, vertex.u, v);
|
||||
};
|
||||
collector->append(cur_liquid.tile, vertices, 4, quad_indices, 6);
|
||||
}
|
||||
|
@ -740,6 +741,19 @@ void MapblockMeshGenerator::drawLiquidTop()
|
|||
for (int i = 0; i < 4; i++) {
|
||||
int u = corner_resolve[i][0];
|
||||
int w = corner_resolve[i][1];
|
||||
|
||||
if (smooth_liquids) {
|
||||
int x = vertices[i].Pos.X > 0;
|
||||
int z = vertices[i].Pos.Z > 0;
|
||||
|
||||
f32 dx = 0.5f * (cur_liquid.neighbors[z][x].level - cur_liquid.neighbors[z][x + 1].level +
|
||||
cur_liquid.neighbors[z + 1][x].level - cur_liquid.neighbors[z + 1][x + 1].level);
|
||||
f32 dz = 0.5f * (cur_liquid.neighbors[z][x].level - cur_liquid.neighbors[z + 1][x].level +
|
||||
cur_liquid.neighbors[z][x + 1].level - cur_liquid.neighbors[z + 1][x + 1].level);
|
||||
|
||||
vertices[i].Normal = v3f(dx, 1., dz).normalize();
|
||||
}
|
||||
|
||||
vertices[i].Pos.Y += cur_liquid.corner_levels[w][u] * BS;
|
||||
if (data->m_smooth_lighting)
|
||||
vertices[i].Color = blendLightColor(vertices[i].Pos);
|
||||
|
@ -779,6 +793,10 @@ void MapblockMeshGenerator::drawLiquidTop()
|
|||
vertex.TCoords += tcoord_center;
|
||||
|
||||
vertex.TCoords += tcoord_translate;
|
||||
|
||||
if (!smooth_liquids) {
|
||||
vertex.Normal = v3f(dx, 1., dz).normalize();
|
||||
}
|
||||
}
|
||||
|
||||
std::swap(vertices[0].TCoords, vertices[2].TCoords);
|
||||
|
|
|
@ -134,6 +134,7 @@ private:
|
|||
f32 corner_levels[2][2];
|
||||
};
|
||||
LiquidData cur_liquid;
|
||||
bool smooth_liquids = false;
|
||||
|
||||
void prepareLiquidNodeDrawing();
|
||||
void getLiquidNeighborhood();
|
||||
|
|
|
@ -386,6 +386,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
|||
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel{"cameraOffset"};
|
||||
CachedVertexShaderSetting<float, 3> m_camera_offset_vertex{"cameraOffset"};
|
||||
CachedPixelShaderSetting<float, 3> m_camera_position_pixel{ "cameraPosition" };
|
||||
CachedVertexShaderSetting<float, 3> m_camera_position_vertex{ "cameraPosition" };
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture0{"texture0"};
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture1{"texture1"};
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture2{"texture2"};
|
||||
|
@ -492,6 +494,10 @@ public:
|
|||
m_camera_offset_pixel.set(offset, services);
|
||||
m_camera_offset_vertex.set(offset, services);
|
||||
|
||||
v3f camera_position = m_client->getCamera()->getPosition();
|
||||
m_camera_position_pixel.set(camera_position, services);
|
||||
m_camera_position_pixel.set(camera_position, services);
|
||||
|
||||
SamplerLayer_t tex_id;
|
||||
tex_id = 0;
|
||||
m_texture0.set(&tex_id, services);
|
||||
|
@ -3184,6 +3190,7 @@ void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *
|
|||
clouds->setDensity(event->cloud_params.density);
|
||||
clouds->setColorBright(video::SColor(event->cloud_params.color_bright));
|
||||
clouds->setColorAmbient(video::SColor(event->cloud_params.color_ambient));
|
||||
clouds->setColorShadow(video::SColor(event->cloud_params.color_shadow));
|
||||
clouds->setHeight(event->cloud_params.height);
|
||||
clouds->setThickness(event->cloud_params.thickness);
|
||||
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
||||
|
@ -4315,7 +4322,9 @@ void Game::updateShadows()
|
|||
float timeoftheday = getWickedTimeOfDay(in_timeofday);
|
||||
bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75;
|
||||
bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible();
|
||||
shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f);
|
||||
const auto &lighting = client->getEnv().getLocalPlayer()->getLighting();
|
||||
shadow->setShadowIntensity(is_shadow_visible ? lighting.shadow_intensity : 0.0f);
|
||||
shadow->setShadowTint(lighting.shadow_tint);
|
||||
|
||||
timeoftheday = std::fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
|
||||
const float offset_constant = 10000.0f;
|
||||
|
|
|
@ -689,6 +689,15 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
|||
if (g_settings->getBool("shadow_poisson_filter"))
|
||||
shaders_header << "#define POISSON_FILTER 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_water_reflections"))
|
||||
shaders_header << "#define ENABLE_WATER_REFLECTIONS 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_translucent_foliage"))
|
||||
shaders_header << "#define ENABLE_TRANSLUCENT_FOLIAGE 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_node_specular"))
|
||||
shaders_header << "#define ENABLE_NODE_SPECULAR 1\n";
|
||||
|
||||
s32 shadow_filter = g_settings->getS32("shadow_filters");
|
||||
shaders_header << "#define SHADOW_FILTER " << shadow_filter << "\n";
|
||||
|
||||
|
|
|
@ -94,9 +94,11 @@ public:
|
|||
bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; }
|
||||
void setTimeOfDay(float isDay) { m_time_day = isDay; };
|
||||
void setShadowIntensity(float shadow_intensity);
|
||||
void setShadowTint(video::SColor shadow_tint) { m_shadow_tint = shadow_tint; }
|
||||
|
||||
s32 getShadowSamples() const { return m_shadow_samples; }
|
||||
float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; }
|
||||
video::SColor getShadowTint() const { return m_shadow_tint; }
|
||||
float getTimeOfDay() const { return m_time_day; }
|
||||
|
||||
f32 getPerspectiveBiasXY() { return m_perspective_bias_xy; }
|
||||
|
@ -131,6 +133,7 @@ private:
|
|||
std::vector<NodeToApply> m_shadow_node_array;
|
||||
|
||||
float m_shadow_strength;
|
||||
video::SColor m_shadow_tint{ 255, 0, 0, 0 };
|
||||
float m_shadow_strength_gamma;
|
||||
float m_shadow_map_max_distance;
|
||||
float m_shadow_map_texture_size;
|
||||
|
|
|
@ -40,6 +40,9 @@ void ShadowConstantSetter::onSetConstants(video::IMaterialRendererServices *serv
|
|||
f32 ShadowStrength = shadow->getShadowStrength();
|
||||
m_shadow_strength.set(&ShadowStrength, services);
|
||||
|
||||
video::SColor ShadowTint = shadow->getShadowTint();
|
||||
m_shadow_tint.set(ShadowTint, services);
|
||||
|
||||
f32 timeOfDay = shadow->getTimeOfDay();
|
||||
m_time_of_day.set(&timeOfDay, services);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class ShadowConstantSetter : public IShaderConstantSetter
|
|||
CachedPixelShaderSetting<f32, 3> m_light_direction{"v_LightDirection"};
|
||||
CachedPixelShaderSetting<f32> m_texture_res{"f_textureresolution"};
|
||||
CachedPixelShaderSetting<f32> m_shadow_strength{"f_shadow_strength"};
|
||||
CachedPixelShaderSetting<f32, 3> m_shadow_tint{ "shadow_tint" };
|
||||
CachedPixelShaderSetting<f32> m_time_of_day{"f_timeofday"};
|
||||
CachedPixelShaderSetting<f32> m_shadowfar{"f_shadowfar"};
|
||||
CachedPixelShaderSetting<f32, 4> m_camera_pos{"CameraPos"};
|
||||
|
|
|
@ -275,6 +275,7 @@ void set_default_settings()
|
|||
settings->setDefault("view_bobbing_amount", "1.0");
|
||||
settings->setDefault("fall_bobbing_amount", "0.03");
|
||||
settings->setDefault("enable_3d_clouds", "true");
|
||||
settings->setDefault("soft_clouds", "false");
|
||||
settings->setDefault("cloud_radius", "12");
|
||||
settings->setDefault("menu_clouds", "true");
|
||||
settings->setDefault("translucent_liquids", "true");
|
||||
|
@ -335,6 +336,9 @@ void set_default_settings()
|
|||
settings->setDefault("bloom_intensity", "0.05");
|
||||
settings->setDefault("bloom_radius", "1");
|
||||
settings->setDefault("enable_volumetric_lighting", "false");
|
||||
settings->setDefault("enable_water_reflections", "false");
|
||||
settings->setDefault("enable_translucent_foliage", "false");
|
||||
settings->setDefault("enable_node_specular", "false");
|
||||
|
||||
// Effects Shadows
|
||||
settings->setDefault("enable_dynamic_shadows", "false");
|
||||
|
|
|
@ -18,7 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#include "SColor.h"
|
||||
|
||||
using namespace irr;
|
||||
|
||||
/**
|
||||
* Parameters for automatic exposure compensation
|
||||
|
@ -54,4 +56,5 @@ struct Lighting
|
|||
float shadow_intensity {0.0f};
|
||||
float saturation {1.0f};
|
||||
float volumetric_light_strength {0.0f};
|
||||
video::SColor shadow_tint;
|
||||
};
|
||||
|
|
|
@ -1476,6 +1476,7 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
|||
f32 density;
|
||||
video::SColor color_bright;
|
||||
video::SColor color_ambient;
|
||||
video::SColor color_shadow = video::SColor(255, 204, 204, 204);
|
||||
f32 height;
|
||||
f32 thickness;
|
||||
v2f speed;
|
||||
|
@ -1483,6 +1484,10 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
|||
*pkt >> density >> color_bright >> color_ambient
|
||||
>> height >> thickness >> speed;
|
||||
|
||||
if (pkt->getRemainingBytes() >= 4) {
|
||||
*pkt >> color_shadow;
|
||||
}
|
||||
|
||||
ClientEvent *event = new ClientEvent();
|
||||
event->type = CE_CLOUD_PARAMS;
|
||||
event->cloud_params.density = density;
|
||||
|
@ -1491,6 +1496,7 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
|||
// we avoid using new() and delete() for no good reason
|
||||
event->cloud_params.color_bright = color_bright.color;
|
||||
event->cloud_params.color_ambient = color_ambient.color;
|
||||
event->cloud_params.color_shadow = color_shadow.color;
|
||||
event->cloud_params.height = height;
|
||||
event->cloud_params.thickness = thickness;
|
||||
// same here: deconstruct to skip constructor
|
||||
|
@ -1821,4 +1827,6 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
|
|||
}
|
||||
if (pkt->getRemainingBytes() >= 4)
|
||||
*pkt >> lighting.volumetric_light_strength;
|
||||
if (pkt->getRemainingBytes() >= 4)
|
||||
*pkt >> lighting.shadow_tint;
|
||||
}
|
||||
|
|
|
@ -229,10 +229,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
[bump for 5.9.1]
|
||||
PROTOCOL VERSION 46:
|
||||
Move default hotbar from client-side C++ to server-side builtin Lua
|
||||
Add shadow tint to Lighting packets
|
||||
Add shadow color to CloudParam packets
|
||||
[scheduled bump for 5.10.0]
|
||||
*/
|
||||
|
||||
#define LATEST_PROTOCOL_VERSION 46
|
||||
|
||||
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
|
||||
|
||||
// Server's supported network protocol range
|
||||
|
@ -1176,4 +1179,4 @@ enum InteractAction : u8
|
|||
INTERACT_PLACE, // 3: place block or item (to abovesurface)
|
||||
INTERACT_USE, // 4: use item
|
||||
INTERACT_ACTIVATE // 5: rightclick air ("activate")
|
||||
};
|
||||
};
|
|
@ -2448,6 +2448,10 @@ int ObjectRef::l_set_clouds(lua_State *L)
|
|||
if (!lua_isnil(L, -1))
|
||||
read_color(L, -1, &cloud_params.color_ambient);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, 2, "shadow");
|
||||
if (!lua_isnil(L, -1))
|
||||
read_color(L, -1, &cloud_params.color_shadow);
|
||||
lua_pop(L, 1);
|
||||
|
||||
cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height);
|
||||
cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
|
||||
|
@ -2483,6 +2487,8 @@ int ObjectRef::l_get_clouds(lua_State *L)
|
|||
lua_setfield(L, -2, "color");
|
||||
push_ARGB8(L, cloud_params.color_ambient);
|
||||
lua_setfield(L, -2, "ambient");
|
||||
push_ARGB8(L, cloud_params.color_shadow);
|
||||
lua_setfield(L, -2, "shadow");
|
||||
lua_pushnumber(L, cloud_params.height);
|
||||
lua_setfield(L, -2, "height");
|
||||
lua_pushnumber(L, cloud_params.thickness);
|
||||
|
@ -2611,6 +2617,8 @@ int ObjectRef::l_set_lighting(lua_State *L)
|
|||
lua_getfield(L, 2, "shadows");
|
||||
if (lua_istable(L, -1)) {
|
||||
getfloatfield(L, -1, "intensity", lighting.shadow_intensity);
|
||||
lua_getfield(L, -1, "tint");
|
||||
read_color(L, -1, &lighting.shadow_tint);
|
||||
}
|
||||
lua_pop(L, 1); // shadows
|
||||
|
||||
|
@ -2654,6 +2662,8 @@ int ObjectRef::l_get_lighting(lua_State *L)
|
|||
lua_newtable(L); // "shadows"
|
||||
lua_pushnumber(L, lighting.shadow_intensity);
|
||||
lua_setfield(L, -2, "intensity");
|
||||
push_ARGB8(L, lighting.shadow_tint);
|
||||
lua_setfield(L, -2, "tint");
|
||||
lua_setfield(L, -2, "shadows");
|
||||
lua_pushnumber(L, lighting.saturation);
|
||||
lua_setfield(L, -2, "saturation");
|
||||
|
|
|
@ -1843,7 +1843,7 @@ void Server::SendCloudParams(session_t peer_id, const CloudParams ¶ms)
|
|||
{
|
||||
NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id);
|
||||
pkt << params.density << params.color_bright << params.color_ambient
|
||||
<< params.height << params.thickness << params.speed;
|
||||
<< params.height << params.thickness << params.speed << params.color_shadow;
|
||||
Send(&pkt);
|
||||
}
|
||||
|
||||
|
@ -1873,7 +1873,7 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
|
|||
<< lighting.exposure.speed_bright_dark
|
||||
<< lighting.exposure.center_weight_power;
|
||||
|
||||
pkt << lighting.volumetric_light_strength;
|
||||
pkt << lighting.volumetric_light_strength << lighting.shadow_tint;
|
||||
|
||||
Send(&pkt);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ struct CloudParams
|
|||
float density;
|
||||
video::SColor color_bright;
|
||||
video::SColor color_ambient;
|
||||
video::SColor color_shadow;
|
||||
float thickness;
|
||||
float height;
|
||||
v2f speed;
|
||||
|
@ -160,6 +161,7 @@ public:
|
|||
clouds.density = 0.4f;
|
||||
clouds.color_bright = video::SColor(229, 240, 240, 255);
|
||||
clouds.color_ambient = video::SColor(255, 0, 0, 0);
|
||||
clouds.color_shadow = video::SColor(255, 204, 204, 204);
|
||||
clouds.thickness = 16.0f;
|
||||
clouds.height = 120;
|
||||
clouds.speed = v2f(0.0f, -2.0f);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue