Fixed the particles light calculation

This commit is contained in:
Andrey2470T 2024-05-01 01:00:30 +03:00
parent 1aa03addec
commit 698a63cc5c
12 changed files with 167 additions and 123 deletions

@ -8,7 +8,6 @@ uniform float fogShadingParameter;
// The cameraOffset is the current center of the visible world.
uniform highp vec3 cameraOffset;
uniform float animationTimer;
#ifdef ENABLE_DYNAMIC_SHADOWS
// shadow texture
uniform sampler2D ShadowMapSampler;
@ -376,7 +375,6 @@ void main(void)
#endif
color = base.rgb;
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
#ifdef ENABLE_DYNAMIC_SHADOWS

@ -8,7 +8,6 @@ uniform float fogShadingParameter;
// The cameraOffset is the current center of the visible world.
uniform highp vec3 cameraOffset;
uniform float animationTimer;
#ifdef ENABLE_DYNAMIC_SHADOWS
// shadow texture
uniform sampler2D ShadowMapSampler;
@ -379,7 +378,6 @@ void main(void)
#endif
color = base.rgb;
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
col.rgb *= vIDiff;

@ -57,6 +57,7 @@ set(client_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp
${CMAKE_CURRENT_SOURCE_DIR}/light_colors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mapblock_mesh.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp

@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h"
#include <algorithm>
#include "client/renderingengine.h"
#include "light_colors.h"
/*
ClientEnvironment

@ -48,6 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/shader.h"
#include "client/minimap.h"
#include <quaternion.h>
#include "light_colors.h"
class Settings;
struct ToolCapabilities;

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/renderingengine.h"
#include "client.h"
#include "noise.h"
#include "light_colors.h"
// Distance of light extrapolation (for oversized nodes)
// After this distance, it gives up and considers light level constant

@ -79,6 +79,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "hud.h"
#include "clientdynamicinfo.h"
#include <IAnimatedMeshSceneNode.h>
#include "light_colors.h"
#if USE_SOUND
#include "client/sound/sound_openal.h"

@ -0,0 +1,98 @@
/*
Minetest
Copyright (C) 2024 Andrey2470T, AndreyT <andreyt2203@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "light_colors.h"
video::SColor encode_light(u16 light, u8 emissive_light)
{
// Get components
u32 day = (light & 0xff);
u32 night = (light >> 8);
// Add emissive light
night += emissive_light * 2.5f;
if (night > 255)
night = 255;
// Since we don't know if the day light is sunlight or
// artificial light, assume it is artificial when the night
// light bank is also lit.
if (day < night)
day = 0;
else
day = day - night;
u32 sum = day + night;
// Ratio of sunlight:
u32 r;
if (sum > 0)
r = day * 255 / sum;
else
r = 0;
// Average light:
float b = (day + night) / 2;
return video::SColor(r, b, b, b);
}
void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){
f32 rg = daynight_ratio / 1000.0f - 0.04f;
f32 b = (0.98f * daynight_ratio) / 1000.0f + 0.078f;
sunlight->r = rg;
sunlight->g = rg;
sunlight->b = b;
}
void final_color_blend(video::SColor *result,
u16 light, u32 daynight_ratio, video::SColor ambientLight)
{
video::SColorf dayLight;
get_sunlight_color(&dayLight, daynight_ratio);
final_color_blend(result,
encode_light(light, 0), dayLight, ambientLight);
}
void final_color_blend(video::SColor *result,
const video::SColor &data, const video::SColorf &dayLight,
video::SColor ambientLight)
{
static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f);
video::SColorf c(data);
f32 n = 1 - c.a;
f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f;
f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f;
f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f;
// Emphase blue a bit in darker places
// Each entry of this array represents a range of 8 blue levels
static const u8 emphase_blue_when_dark[32] = {
1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255),
0, 255) / 8] / 255.0f;
// Add ambient light
r += ambientLight.getRed() / 255.f;
g += ambientLight.getGreen() / 255.f;
b += ambientLight.getBlue() / 255.f;
result->setRed(core::clamp((s32)(r * 255.f), 0, 255));
result->setGreen(core::clamp((s32)(g * 255.f), 0, 255));
result->setBlue(core::clamp((s32)(b * 255.f), 0, 255));
}

61
src/client/light_colors.h Normal file

@ -0,0 +1,61 @@
/*
Minetest
Copyright (C) 2024 Andrey2470T, AndreyT <andreyt2203@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "irrlichttypes_extrabloated.h"
/*!
* Encodes light of a node.
* The result is not the final color, but a
* half-baked vertex color.
* You have to multiply the resulting color
* with the node's color.
*
* \param light the first 8 bits are day light,
* the last 8 bits are night light
* \param emissive_light amount of light the surface emits,
* from 0 to LIGHT_SUN.
*/
video::SColor encode_light(u16 light, u8 emissive_light);
/*!
* Returns the sunlight's color from the current
* day-night ratio.
*/
void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio);
/*!
* Gives the final SColor shown on screen.
*
* \param result output color
* \param light first 8 bits are day light, second 8 bits are
* night light
*/
void final_color_blend(video::SColor *result,
u16 light, u32 daynight_ratio, video::SColor ambientLight=video::SColor(255,0,0,0));
/*!
* Gives the final SColor shown on screen.
*
* \param result output color
* \param data the half-baked vertex color
* \param dayLight color of the sunlight
*/
void final_color_blend(video::SColor *result,
const video::SColor &data, const video::SColorf &dayLight,
video::SColor ambientLight=video::SColor(255,0,0,0));

@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <algorithm>
#include <cmath>
#include "client/texturesource.h"
#include "light_colors.h"
/*
MeshMakeData
@ -281,55 +282,6 @@ u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData
return getSmoothLightCombined(p, dirs, data);
}
void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){
f32 rg = daynight_ratio / 1000.0f - 0.04f;
f32 b = (0.98f * daynight_ratio) / 1000.0f + 0.078f;
sunlight->r = rg;
sunlight->g = rg;
sunlight->b = b;
}
void final_color_blend(video::SColor *result,
u16 light, u32 daynight_ratio, video::SColor ambientLight)
{
video::SColorf dayLight;
get_sunlight_color(&dayLight, daynight_ratio);
final_color_blend(result,
encode_light(light, 0), dayLight, ambientLight);
}
void final_color_blend(video::SColor *result,
const video::SColor &data, const video::SColorf &dayLight,
video::SColor ambientLight)
{
static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f);
video::SColorf c(data);
f32 n = 1 - c.a;
f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f;
f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f;
f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f;
// Emphase blue a bit in darker places
// Each entry of this array represents a range of 8 blue levels
static const u8 emphase_blue_when_dark[32] = {
1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255),
0, 255) / 8] / 255.0f;
// Add ambient light
r += ambientLight.getRed() / 255.f;
g += ambientLight.getGreen() / 255.f;
b += ambientLight.getBlue() / 255.f;
result->setRed(core::clamp((s32)(r * 255.f), 0, 255));
result->setGreen(core::clamp((s32)(g * 255.f), 0, 255));
result->setBlue(core::clamp((s32)(b * 255.f), 0, 255));
}
/*
Mesh generation helpers
@ -955,34 +907,6 @@ void MapBlockMesh::consolidateTransparentBuffers()
}
}
video::SColor encode_light(u16 light, u8 emissive_light)
{
// Get components
u32 day = (light & 0xff);
u32 night = (light >> 8);
// Add emissive light
night += emissive_light * 2.5f;
if (night > 255)
night = 255;
// Since we don't know if the day light is sunlight or
// artificial light, assume it is artificial when the night
// light bank is also lit.
if (day < night)
day = 0;
else
day = day - night;
u32 sum = day + night;
// Ratio of sunlight:
u32 r;
if (sum > 0)
r = day * 255 / sum;
else
r = 0;
// Average light:
float b = (day + night) / 2;
return video::SColor(r, b, b, b);
}
u8 get_solid_sides(MeshMakeData *data)
{
std::unordered_map<v3s16, u8> results;

@ -284,53 +284,12 @@ class MapBlockMesh
std::vector<PartialMeshBuffer> m_transparent_buffers;
};
/*!
* Encodes light of a node.
* The result is not the final color, but a
* half-baked vertex color.
* You have to multiply the resulting color
* with the node's color.
*
* \param light the first 8 bits are day light,
* the last 8 bits are night light
* \param emissive_light amount of light the surface emits,
* from 0 to LIGHT_SUN.
*/
video::SColor encode_light(u16 light, u8 emissive_light);
// Compute light at node
u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef);
u16 getFaceLight(MapNode n, MapNode n2, const NodeDefManager *ndef);
u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data);
u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data);
/*!
* Returns the sunlight's color from the current
* day-night ratio.
*/
void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio);
/*!
* Gives the final SColor shown on screen.
*
* \param result output color
* \param light first 8 bits are day light, second 8 bits are
* night light
*/
void final_color_blend(video::SColor *result,
u16 light, u32 daynight_ratio, video::SColor ambientLight=video::SColor(255,0,0,0));
/*!
* Gives the final SColor shown on screen.
*
* \param result output color
* \param data the half-baked vertex color
* \param dayLight color of the sunlight
*/
void final_color_blend(video::SColor *result,
const video::SColor &data, const video::SColorf &dayLight,
video::SColor ambientLight=video::SColor(255,0,0,0));
// Retrieves the TileSpec of a face of a node
// Adds MATERIAL_FLAG_CRACK if the node is cracked
// TileSpec should be passed as reference due to the underlying TileFrame and its vector

@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "profiler.h"
#include "client/mapblock_mesh.h"
#include "light_colors.h"
ClientParticleTexture::ClientParticleTexture(const ServerParticleTexture& p, ITextureSource *tsrc)
{
@ -186,7 +187,7 @@ video::SColor Particle::updateLight(ClientEnvironment *env)
else
light = blend_light(env->getDayNightRatio(), LIGHT_SUN, 0);
light += m_p.glow;
light = decode_light(light + m_p.glow);
video::SColor light_color{0xFFFFFFFF};