mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
Dynamic sky, fog and cloud colors; sun and moon
This commit is contained in:
parent
58bed83d03
commit
2e90ed07ac
30 changed files with 1132 additions and 244 deletions
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "client.h"
|
||||
#include "mapblock_mesh.h"
|
||||
#include <IMaterialRenderer.h>
|
||||
#include <matrix4.h>
|
||||
#include "log.h"
|
||||
#include "mapsector.h"
|
||||
#include "main.h" // dout_client, g_settings
|
||||
|
@ -29,6 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "profiler.h"
|
||||
#include "settings.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
ClientMap::ClientMap(
|
||||
Client *client,
|
||||
IGameDef *gamedef,
|
||||
|
@ -189,7 +192,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||
*/
|
||||
float animation_time = m_client->getAnimationTime();
|
||||
int crack = m_client->getCrackLevel();
|
||||
u32 daynight_ratio = m_client->getDayNightRatio();
|
||||
u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
|
||||
|
||||
m_camera_mutex.Lock();
|
||||
v3f camera_position = m_camera_position;
|
||||
|
@ -509,6 +512,182 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||
<<", rendered "<<vertex_count<<" vertices."<<std::endl;*/
|
||||
}
|
||||
|
||||
static bool getVisibleBrightness(Map *map, v3f p0, v3f dir, float step,
|
||||
float step_multiplier, float start_distance, float end_distance,
|
||||
INodeDefManager *ndef, u32 daylight_factor, float sunlight_min_d,
|
||||
int *result, bool *sunlight_seen)
|
||||
{
|
||||
int brightness_sum = 0;
|
||||
int brightness_count = 0;
|
||||
float distance = start_distance;
|
||||
dir.normalize();
|
||||
v3f pf = p0;
|
||||
pf += dir * distance;
|
||||
int noncount = 0;
|
||||
bool nonlight_seen = false;
|
||||
bool allow_allowing_non_sunlight_propagates = false;
|
||||
bool allow_non_sunlight_propagates = false;
|
||||
// Check content nearly at camera position
|
||||
{
|
||||
v3s16 p = floatToInt(p0 /*+ dir * 3*BS*/, BS);
|
||||
MapNode n = map->getNodeNoEx(p);
|
||||
if(ndef->get(n).param_type == CPT_LIGHT &&
|
||||
!ndef->get(n).sunlight_propagates)
|
||||
allow_allowing_non_sunlight_propagates = true;
|
||||
}
|
||||
// If would start at CONTENT_IGNORE, start closer
|
||||
{
|
||||
v3s16 p = floatToInt(pf, BS);
|
||||
MapNode n = map->getNodeNoEx(p);
|
||||
if(n.getContent() == CONTENT_IGNORE){
|
||||
float newd = 2*BS;
|
||||
pf = p0 + dir * 2*newd;
|
||||
distance = newd;
|
||||
}
|
||||
}
|
||||
for(int i=0; distance < end_distance; i++){
|
||||
pf += dir * step;
|
||||
distance += step;
|
||||
step *= step_multiplier;
|
||||
|
||||
v3s16 p = floatToInt(pf, BS);
|
||||
MapNode n = map->getNodeNoEx(p);
|
||||
if(allow_allowing_non_sunlight_propagates && i == 0 &&
|
||||
ndef->get(n).param_type == CPT_LIGHT &&
|
||||
!ndef->get(n).sunlight_propagates){
|
||||
allow_non_sunlight_propagates = true;
|
||||
}
|
||||
if(ndef->get(n).param_type != CPT_LIGHT ||
|
||||
(!ndef->get(n).sunlight_propagates &&
|
||||
!allow_non_sunlight_propagates)){
|
||||
nonlight_seen = true;
|
||||
noncount++;
|
||||
if(noncount >= 4)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if(distance >= sunlight_min_d && *sunlight_seen == false
|
||||
&& nonlight_seen == false)
|
||||
if(n.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN)
|
||||
*sunlight_seen = true;
|
||||
noncount = 0;
|
||||
brightness_sum += decode_light(n.getLightBlend(daylight_factor, ndef));
|
||||
brightness_count++;
|
||||
}
|
||||
*result = 0;
|
||||
if(brightness_count == 0)
|
||||
return false;
|
||||
*result = brightness_sum / brightness_count;
|
||||
/*std::cerr<<"Sampled "<<brightness_count<<" points; result="
|
||||
<<(*result)<<std::endl;*/
|
||||
return true;
|
||||
}
|
||||
|
||||
int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
|
||||
int oldvalue, bool *sunlight_seen_result)
|
||||
{
|
||||
const bool debugprint = false;
|
||||
INodeDefManager *ndef = m_gamedef->ndef();
|
||||
static v3f z_directions[50] = {
|
||||
v3f(-100, 0, 0)
|
||||
};
|
||||
static f32 z_offsets[sizeof(z_directions)/sizeof(*z_directions)] = {
|
||||
-1000,
|
||||
};
|
||||
if(z_directions[0].X < -99){
|
||||
for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
|
||||
z_directions[i] = v3f(
|
||||
0.01 * myrand_range(-80, 80),
|
||||
1.0,
|
||||
0.01 * myrand_range(-80, 80)
|
||||
);
|
||||
z_offsets[i] = 0.01 * myrand_range(0,100);
|
||||
}
|
||||
}
|
||||
if(debugprint)
|
||||
std::cerr<<"In goes "<<PP(m_camera_direction)<<", out comes ";
|
||||
int sunlight_seen_count = 0;
|
||||
float sunlight_min_d = max_d*0.8;
|
||||
if(sunlight_min_d > 35*BS)
|
||||
sunlight_min_d = 35*BS;
|
||||
core::array<int> values;
|
||||
for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
|
||||
v3f z_dir = z_directions[i];
|
||||
z_dir.normalize();
|
||||
core::CMatrix4<f32> a;
|
||||
a.buildRotateFromTo(v3f(0,1,0), z_dir);
|
||||
v3f dir = m_camera_direction;
|
||||
a.rotateVect(dir);
|
||||
int br = 0;
|
||||
float step = BS*1.5;
|
||||
if(max_d > 35*BS)
|
||||
step = max_d / 35 * 1.5;
|
||||
float off = step * z_offsets[i];
|
||||
bool sunlight_seen_now = false;
|
||||
bool ok = getVisibleBrightness(this, m_camera_position, dir,
|
||||
step, 1.0, max_d*0.6+off, max_d, ndef, daylight_factor,
|
||||
sunlight_min_d,
|
||||
&br, &sunlight_seen_now);
|
||||
if(sunlight_seen_now)
|
||||
sunlight_seen_count++;
|
||||
if(!ok)
|
||||
continue;
|
||||
values.push_back(br);
|
||||
// Don't try too much if being in the sun is clear
|
||||
if(sunlight_seen_count >= 20)
|
||||
break;
|
||||
}
|
||||
int brightness_sum = 0;
|
||||
int brightness_count = 0;
|
||||
values.sort();
|
||||
u32 num_values_to_use = values.size();
|
||||
if(num_values_to_use >= 10)
|
||||
num_values_to_use -= num_values_to_use/2;
|
||||
else if(num_values_to_use >= 7)
|
||||
num_values_to_use -= num_values_to_use/3;
|
||||
u32 first_value_i = (values.size() - num_values_to_use) / 2;
|
||||
if(debugprint){
|
||||
for(u32 i=0; i < first_value_i; i++)
|
||||
std::cerr<<values[i]<<" ";
|
||||
std::cerr<<"[";
|
||||
}
|
||||
for(u32 i=first_value_i; i < first_value_i+num_values_to_use; i++){
|
||||
if(debugprint)
|
||||
std::cerr<<values[i]<<" ";
|
||||
brightness_sum += values[i];
|
||||
brightness_count++;
|
||||
}
|
||||
if(debugprint){
|
||||
std::cerr<<"]";
|
||||
for(u32 i=first_value_i+num_values_to_use; i < values.size(); i++)
|
||||
std::cerr<<values[i]<<" ";
|
||||
}
|
||||
int ret = 0;
|
||||
if(brightness_count == 0){
|
||||
MapNode n = getNodeNoEx(floatToInt(m_camera_position, BS));
|
||||
if(ndef->get(n).param_type == CPT_LIGHT){
|
||||
ret = decode_light(n.getLightBlend(daylight_factor, ndef));
|
||||
} else {
|
||||
ret = oldvalue;
|
||||
//ret = blend_light(255, 0, daylight_factor);
|
||||
}
|
||||
} else {
|
||||
/*float pre = (float)brightness_sum / (float)brightness_count;
|
||||
float tmp = pre;
|
||||
const float d = 0.2;
|
||||
pre *= 1.0 + d*2;
|
||||
pre -= tmp * d;
|
||||
int preint = pre;
|
||||
ret = MYMAX(0, MYMIN(255, preint));*/
|
||||
ret = brightness_sum / brightness_count;
|
||||
}
|
||||
if(debugprint)
|
||||
std::cerr<<"Result: "<<ret<<" sunlight_seen_count="
|
||||
<<sunlight_seen_count<<std::endl;
|
||||
*sunlight_seen_result = (sunlight_seen_count > 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ClientMap::renderPostFx()
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue