From 6bb43472082d8003a6cd140c1221c81005fdd752 Mon Sep 17 00:00:00 2001 From: lhofhansl Date: Fri, 4 Nov 2016 10:12:45 -0700 Subject: Remove unused shader matrices. (#4723) --- src/shader.cpp | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/shader.cpp') diff --git a/src/shader.cpp b/src/shader.cpp index e13ab8df3..b0131c952 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -219,14 +219,6 @@ public: video::IVideoDriver *driver = services->getVideoDriver(); sanity_check(driver); - // set inverted world matrix - core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD); - invWorld.makeInverse(); - if(is_highlevel) - services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16); - else - services->setVertexShaderConstant(invWorld.pointer(), 0, 4); - // set clip matrix core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); @@ -237,14 +229,6 @@ public: else services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4); - // set transposed world matrix - core::matrix4 transWorld = driver->getTransform(video::ETS_WORLD); - transWorld = transWorld.getTransposed(); - if(is_highlevel) - services->setVertexShaderConstant("mTransWorld", transWorld.pointer(), 16); - else - services->setVertexShaderConstant(transWorld.pointer(), 8, 4); - // set world matrix core::matrix4 world = driver->getTransform(video::ETS_WORLD); if(is_highlevel) -- cgit v1.2.3 From 4bf4154cad127560ffe831e7b2cd1a0b960d0f03 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 22 Nov 2016 09:05:39 -0500 Subject: Fix superflous shader setting updates (#4800) This improves rendering performance by ~40% --- src/game.cpp | 184 +++++++++++++++++++++++++++++++++++++++------------------ src/shader.cpp | 129 +++++++++++++++++++++------------------- src/shader.h | 63 +++++++++++++++++--- 3 files changed, 249 insertions(+), 127 deletions(-) (limited to 'src/shader.cpp') diff --git a/src/game.cpp b/src/game.cpp index e0ffa1be5..16287fe0d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -888,40 +888,73 @@ public: } }; + +// before 1.8 there isn't a "integer interface", only float +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) +typedef f32 SamplerLayer_t; +#else +typedef s32 SamplerLayer_t; +#endif + + class GameGlobalShaderConstantSetter : public IShaderConstantSetter { Sky *m_sky; bool *m_force_fog_off; f32 *m_fog_range; + bool m_fog_enabled; + CachedPixelShaderSetting m_sky_bg_color; + CachedPixelShaderSetting m_fog_distance; + CachedVertexShaderSetting m_animation_timer_vertex; + CachedPixelShaderSetting m_animation_timer_pixel; + CachedPixelShaderSetting m_day_night_ratio; + CachedPixelShaderSetting m_eye_position_pixel; + CachedVertexShaderSetting m_eye_position_vertex; + CachedPixelShaderSetting m_minimap_yaw; + CachedPixelShaderSetting m_base_texture; + CachedPixelShaderSetting m_normal_texture; + CachedPixelShaderSetting m_texture_flags; Client *m_client; - bool m_fogEnabled; public: void onSettingsChange(const std::string &name) { if (name == "enable_fog") - m_fogEnabled = g_settings->getBool("enable_fog"); + m_fog_enabled = g_settings->getBool("enable_fog"); } - static void SettingsCallback(const std::string &name, void *userdata) + static void settingsCallback(const std::string &name, void *userdata) { reinterpret_cast(userdata)->onSettingsChange(name); } + void setSky(Sky *sky) { m_sky = sky; } + GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off, f32 *fog_range, Client *client) : m_sky(sky), m_force_fog_off(force_fog_off), m_fog_range(fog_range), + m_sky_bg_color("skyBgColor"), + m_fog_distance("fogDistance"), + m_animation_timer_vertex("animationTimer"), + m_animation_timer_pixel("animationTimer"), + m_day_night_ratio("dayNightRatio"), + m_eye_position_pixel("eyePosition"), + m_eye_position_vertex("eyePosition"), + m_minimap_yaw("yawVec"), + m_base_texture("baseTexture"), + m_normal_texture("normalTexture"), + m_texture_flags("textureFlags"), m_client(client) { - g_settings->registerChangedCallback("enable_fog", SettingsCallback, this); - m_fogEnabled = g_settings->getBool("enable_fog"); + g_settings->registerChangedCallback("enable_fog", settingsCallback, this); + m_fog_enabled = g_settings->getBool("enable_fog"); } ~GameGlobalShaderConstantSetter() { - g_settings->deregisterChangedCallback("enable_fog", SettingsCallback, this); + g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this); } virtual void onSetConstants(video::IMaterialRendererServices *services, @@ -939,54 +972,92 @@ public: bgcolorf.b, bgcolorf.a, }; - services->setPixelShaderConstant("skyBgColor", bgcolorfa, 4); + m_sky_bg_color.set(bgcolorfa, services); // Fog distance float fog_distance = 10000 * BS; - if (m_fogEnabled && !*m_force_fog_off) + if (m_fog_enabled && !*m_force_fog_off) fog_distance = *m_fog_range; - services->setPixelShaderConstant("fogDistance", &fog_distance, 1); + m_fog_distance.set(&fog_distance, services); - // Day-night ratio - u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); - float daynight_ratio_f = (float)daynight_ratio / 1000.0; - services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1); + float daynight_ratio = (float)m_client->getEnv().getDayNightRatio() / 1000.f; + m_day_night_ratio.set(&daynight_ratio, services); u32 animation_timer = porting::getTimeMs() % 100000; - float animation_timer_f = (float)animation_timer / 100000.0; - services->setPixelShaderConstant("animationTimer", &animation_timer_f, 1); - services->setVertexShaderConstant("animationTimer", &animation_timer_f, 1); + float animation_timer_f = (float)animation_timer / 100000.f; + m_animation_timer_vertex.set(&animation_timer_f, services); + m_animation_timer_pixel.set(&animation_timer_f, services); - LocalPlayer *player = m_client->getEnv().getLocalPlayer(); - v3f eye_position = player->getEyePosition(); - services->setPixelShaderConstant("eyePosition", (irr::f32 *)&eye_position, 3); - services->setVertexShaderConstant("eyePosition", (irr::f32 *)&eye_position, 3); - - v3f minimap_yaw_vec = m_client->getMapper()->getYawVec(); - services->setPixelShaderConstant("yawVec", (irr::f32 *)&minimap_yaw_vec, 3); + float eye_position_array[3]; + v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition(); +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) + eye_position_array[0] = epos.X; + eye_position_array[1] = epos.Y; + eye_position_array[2] = epos.Z; +#else + epos.getAs3Values(eye_position_array); +#endif + m_eye_position_pixel.set(eye_position_array, services); + m_eye_position_vertex.set(eye_position_array, services); - // Uniform sampler layers - // before 1.8 there isn't a "integer interface", only float + float minimap_yaw_array[3]; + v3f minimap_yaw = m_client->getMapper()->getYawVec(); #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) - f32 layer0 = 0; - f32 layer1 = 1; - f32 layer2 = 2; - services->setPixelShaderConstant("baseTexture" , (irr::f32 *)&layer0, 1); - services->setPixelShaderConstant("normalTexture" , (irr::f32 *)&layer1, 1); - services->setPixelShaderConstant("textureFlags" , (irr::f32 *)&layer2, 1); + minimap_yaw_array[0] = minimap_yaw.X; + minimap_yaw_array[1] = minimap_yaw.Y; + minimap_yaw_array[2] = minimap_yaw.Z; #else - s32 layer0 = 0; - s32 layer1 = 1; - s32 layer2 = 2; - services->setPixelShaderConstant("baseTexture" , (irr::s32 *)&layer0, 1); - services->setPixelShaderConstant("normalTexture" , (irr::s32 *)&layer1, 1); - services->setPixelShaderConstant("textureFlags" , (irr::s32 *)&layer2, 1); + minimap_yaw.getAs3Values(minimap_yaw_array); #endif + m_minimap_yaw.set(minimap_yaw_array, services); + + SamplerLayer_t base_tex = 0, + normal_tex = 1, + flags_tex = 2; + m_base_texture.set(&base_tex, services); + m_normal_texture.set(&normal_tex, services); + m_texture_flags.set(&flags_tex, services); } }; + +class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ + Sky *m_sky; + bool *m_force_fog_off; + f32 *m_fog_range; + Client *m_client; + std::vector created_nosky; +public: + GameGlobalShaderConstantSetterFactory(bool *force_fog_off, + f32 *fog_range, Client *client) : + m_sky(NULL), + m_force_fog_off(force_fog_off), + m_fog_range(fog_range), + m_client(client) + {} + + void setSky(Sky *sky) { + m_sky = sky; + for (size_t i = 0; i < created_nosky.size(); ++i) { + created_nosky[i]->setSky(m_sky); + } + created_nosky.clear(); + } + + virtual IShaderConstantSetter* create() + { + GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter( + m_sky, m_force_fog_off, m_fog_range, m_client); + if (!m_sky) + created_nosky.push_back(scs); + return scs; + } +}; + + bool nodePlacementPrediction(Client &client, const ItemDefinition &playeritem_def, v3s16 nodepos, v3s16 neighbourpos) { @@ -1695,6 +1766,9 @@ private: Hud *hud; Mapper *mapper; + GameRunData runData; + VolatileRunFlags flags; + /* 'cache' This class does take ownership/responsibily for cleaning up etc of any of these items (e.g. device) @@ -1886,6 +1960,18 @@ bool Game::startup(bool *kill, smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true); + memset(&runData, 0, sizeof(runData)); + runData.time_from_last_punch = 10.0; + runData.profiler_max_page = 3; + runData.update_wielded_item_trigger = true; + + memset(&flags, 0, sizeof(flags)); + flags.show_chat = true; + flags.show_hud = true; + flags.show_debug = g_settings->getBool("show_debug"); + flags.invert_mouse = g_settings->getBool("invert_mouse"); + flags.first_loop_after_window_activation = true; + if (!init(map_dir, address, port, gamespec)) return false; @@ -1902,34 +1988,15 @@ void Game::run() RunStats stats = { 0 }; CameraOrientation cam_view_target = { 0 }; CameraOrientation cam_view = { 0 }; - GameRunData runData = { 0 }; FpsControl draw_times = { 0 }; - VolatileRunFlags flags = { 0 }; f32 dtime; // in seconds - runData.time_from_last_punch = 10.0; - runData.profiler_max_page = 3; - runData.update_wielded_item_trigger = true; - - flags.show_chat = true; - flags.show_hud = true; - flags.show_minimap = g_settings->getBool("enable_minimap"); - flags.show_debug = g_settings->getBool("show_debug"); - flags.invert_mouse = g_settings->getBool("invert_mouse"); - flags.first_loop_after_window_activation = true; - /* Clear the profiler */ Profiler::GraphValues dummyvalues; g_profiler->graphGet(dummyvalues); draw_times.last_time = device->getTimer()->getTime(); - shader_src->addGlobalConstantSetter(new GameGlobalShaderConstantSetter( - sky, - &flags.force_fog_off, - &runData.fog_range, - client)); - set_light_table(g_settings->getFloat("display_gamma")); #ifdef __ANDROID__ @@ -2169,6 +2236,10 @@ bool Game::createClient(const std::string &playername, return false; } + GameGlobalShaderConstantSetterFactory *scsf = new GameGlobalShaderConstantSetterFactory( + &flags.force_fog_off, &runData.fog_range, client); + shader_src->addShaderConstantSetterFactory(scsf); + // Update cached textures, meshes and materials client->afterContentReceived(device); @@ -2193,6 +2264,7 @@ bool Game::createClient(const std::string &playername, /* Skybox */ sky = new Sky(smgr->getRootSceneNode(), smgr, -1, texture_src); + scsf->setSky(sky); skybox = NULL; // This is used/set later on in the main run loop local_inventory = new Inventory(itemdef_manager); diff --git a/src/shader.cpp b/src/shader.cpp index b0131c952..170b0354d 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -167,29 +167,27 @@ private: } }; + /* ShaderCallback: Sets constants that can be used in shaders */ -class IShaderConstantSetterRegistry -{ -public: - virtual ~IShaderConstantSetterRegistry(){}; - virtual void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel, const std::string &name) = 0; -}; - class ShaderCallback : public video::IShaderConstantSetCallBack { - IShaderConstantSetterRegistry *m_scsr; - std::string m_name; + std::vector m_setters; public: - ShaderCallback(IShaderConstantSetterRegistry *scsr, const std::string &name): - m_scsr(scsr), - m_name(name) - {} - ~ShaderCallback() {} + ShaderCallback(const std::vector &factories) + { + for (u32 i = 0; i < factories.size(); ++i) + m_setters.push_back(factories[i]->create()); + } + + ~ShaderCallback() + { + for (u32 i = 0; i < m_setters.size(); ++i) + delete m_setters[i]; + } virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) { @@ -198,18 +196,25 @@ public: bool is_highlevel = userData; - m_scsr->onSetConstants(services, is_highlevel, m_name); + for (u32 i = 0; i < m_setters.size(); ++i) + m_setters[i]->onSetConstants(services, is_highlevel); } }; + /* MainShaderConstantSetter: Set basic constants required for almost everything */ class MainShaderConstantSetter : public IShaderConstantSetter { + CachedVertexShaderSetting m_world_view_proj; + CachedVertexShaderSetting m_world; + public: - MainShaderConstantSetter(IrrlichtDevice *device) + MainShaderConstantSetter() : + m_world_view_proj("mWorldViewProj"), + m_world("mWorld") {} ~MainShaderConstantSetter() {} @@ -219,31 +224,40 @@ public: video::IVideoDriver *driver = services->getVideoDriver(); sanity_check(driver); - // set clip matrix + // Set clip matrix core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); worldViewProj *= driver->getTransform(video::ETS_VIEW); worldViewProj *= driver->getTransform(video::ETS_WORLD); - if(is_highlevel) - services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16); + if (is_highlevel) + m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); else - services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4); + services->setVertexShaderConstant(worldViewProj.pointer(), 0, 4); - // set world matrix + // Set world matrix core::matrix4 world = driver->getTransform(video::ETS_WORLD); - if(is_highlevel) - services->setVertexShaderConstant("mWorld", world.pointer(), 16); + if (is_highlevel) + m_world.set(*reinterpret_cast(world.pointer()), services); else - services->setVertexShaderConstant(world.pointer(), 8, 4); + services->setVertexShaderConstant(world.pointer(), 4, 4); } }; + +class MainShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ +public: + virtual IShaderConstantSetter* create() + { return new MainShaderConstantSetter(); } +}; + + /* ShaderSource */ -class ShaderSource : public IWritableShaderSource, public IShaderConstantSetterRegistry +class ShaderSource : public IWritableShaderSource { public: ShaderSource(IrrlichtDevice *device); @@ -286,22 +300,17 @@ public: // Shall be called from the main thread. void rebuildShaders(); - void addGlobalConstantSetter(IShaderConstantSetter *setter) + void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) { - m_global_setters.push_back(setter); + m_setter_factories.push_back(setter); } - void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel, const std::string &name); - private: // The id of the thread that is allowed to use irrlicht directly threadid_t m_main_thread; // The irrlicht device IrrlichtDevice *m_device; - // The set-constants callback - ShaderCallback *m_shader_callback; // Cache of source shaders // This should be only accessed from the main thread @@ -316,9 +325,11 @@ private: // Queued shader fetches (to be processed by the main thread) RequestQueue m_get_shader_queue; - // Global constant setters - // TODO: Delete these in the destructor - std::vector m_global_setters; + // Global constant setter factories + std::vector m_setter_factories; + + // Shader callbacks + std::vector m_callbacks; }; IWritableShaderSource* createShaderSource(IrrlichtDevice *device) @@ -331,8 +342,8 @@ IWritableShaderSource* createShaderSource(IrrlichtDevice *device) */ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, - IrrlichtDevice *device, - video::IShaderConstantSetCallBack *callback, + IrrlichtDevice *device, std::vector &callbacks, + const std::vector &setter_factories, SourceShaderCache *sourcecache); /* @@ -348,28 +359,24 @@ ShaderSource::ShaderSource(IrrlichtDevice *device): { assert(m_device); // Pre-condition - m_shader_callback = new ShaderCallback(this, "default"); - m_main_thread = thr_get_current_thread_id(); // Add a dummy ShaderInfo as the first index, named "" m_shaderinfo_cache.push_back(ShaderInfo()); // Add main global constant setter - addGlobalConstantSetter(new MainShaderConstantSetter(device)); + addShaderConstantSetterFactory(new MainShaderConstantSetterFactory()); } ShaderSource::~ShaderSource() { - for (std::vector::iterator iter = m_global_setters.begin(); - iter != m_global_setters.end(); ++iter) { + for (std::vector::iterator iter = m_callbacks.begin(); + iter != m_callbacks.end(); ++iter) { delete *iter; } - m_global_setters.clear(); - - if (m_shader_callback) { - m_shader_callback->drop(); - m_shader_callback = NULL; + for (std::vector::iterator iter = m_setter_factories.begin(); + iter != m_setter_factories.end(); ++iter) { + delete *iter; } } @@ -445,8 +452,8 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name, return 0; } - ShaderInfo info = generate_shader(name, material_type, drawtype, m_device, - m_shader_callback, &m_sourcecache); + ShaderInfo info = generate_shader(name, material_type, drawtype, + m_device, m_callbacks, m_setter_factories, &m_sourcecache); /* Add shader to caches (add dummy shaders too) @@ -511,22 +518,16 @@ void ShaderSource::rebuildShaders() ShaderInfo *info = &m_shaderinfo_cache[i]; if(info->name != ""){ *info = generate_shader(info->name, info->material_type, - info->drawtype, m_device, m_shader_callback, &m_sourcecache); + info->drawtype, m_device, m_callbacks, + m_setter_factories, &m_sourcecache); } } } -void ShaderSource::onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel, const std::string &name) -{ - for(u32 i=0; ionSetConstants(services, is_highlevel); - } -} ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, - IrrlichtDevice *device, video::IShaderConstantSetCallBack *callback, + IrrlichtDevice *device, std::vector &callbacks, + const std::vector &setter_factories, SourceShaderCache *sourcecache) { ShaderInfo shaderinfo; @@ -766,6 +767,7 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, geometry_program = shaders_header + geometry_program; geometry_program_ptr = geometry_program.c_str(); } + ShaderCallback *cb = new ShaderCallback(setter_factories); s32 shadermat = -1; if(is_highlevel){ infostream<<"Compiling high level shaders for "<addShaderMaterial( vertex_program_ptr, // Vertex shader program pixel_program_ptr, // Pixel shader program - callback, // Set-constant callback + cb, // Set-constant callback shaderinfo.base_material, // Base material 0 // Userdata passed to callback ); @@ -814,9 +817,11 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, < #include "irrlichttypes_extrabloated.h" #include "threads.h" #include @@ -43,8 +44,7 @@ class IGameDef; std::string getShaderPath(const std::string &name_of_shader, const std::string &filename); -struct ShaderInfo -{ +struct ShaderInfo { std::string name; video::E_MATERIAL_TYPE base_material; video::E_MATERIAL_TYPE material; @@ -66,20 +66,66 @@ namespace irr { namespace video { class IMaterialRendererServices; } } -class IShaderConstantSetter -{ + +class IShaderConstantSetter { public: virtual ~IShaderConstantSetter(){}; virtual void onSetConstants(video::IMaterialRendererServices *services, bool is_highlevel) = 0; }; + +class IShaderConstantSetterFactory { +public: + virtual ~IShaderConstantSetterFactory() {}; + virtual IShaderConstantSetter* create() = 0; +}; + + +template +class CachedShaderSetting { + const char *m_name; + T m_sent[count]; + bool has_been_set; + bool is_pixel; +protected: + CachedShaderSetting(const char *name, bool is_pixel) : + m_name(name), has_been_set(false), is_pixel(is_pixel) + {} +public: + void set(const T value[count], video::IMaterialRendererServices *services) + { + if (has_been_set && std::equal(m_sent, m_sent + count, value)) + return; + if (is_pixel) + services->setPixelShaderConstant(m_name, value, count); + else + services->setVertexShaderConstant(m_name, value, count); + std::copy(value, value + count, m_sent); + has_been_set = true; + } +}; + +template +class CachedPixelShaderSetting : public CachedShaderSetting { +public: + CachedPixelShaderSetting(const char *name) : + CachedShaderSetting(name, true){} +}; + +template +class CachedVertexShaderSetting : public CachedShaderSetting { +public: + CachedVertexShaderSetting(const char *name) : + CachedShaderSetting(name, false){} +}; + + /* ShaderSource creates and caches shaders. */ -class IShaderSource -{ +class IShaderSource { public: IShaderSource(){} virtual ~IShaderSource(){} @@ -90,8 +136,7 @@ public: const u8 material_type, const u8 drawtype){return 0;} }; -class IWritableShaderSource : public IShaderSource -{ +class IWritableShaderSource : public IShaderSource { public: IWritableShaderSource(){} virtual ~IWritableShaderSource(){} @@ -105,7 +150,7 @@ public: virtual void insertSourceShader(const std::string &name_of_shader, const std::string &filename, const std::string &program)=0; virtual void rebuildShaders()=0; - virtual void addGlobalConstantSetter(IShaderConstantSetter *setter)=0; + virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0; }; IWritableShaderSource* createShaderSource(IrrlichtDevice *device); -- cgit v1.2.3 From dbeb322f62bfdd431365622a6f5ddfae062c0d31 Mon Sep 17 00:00:00 2001 From: Zeno- Date: Wed, 23 Nov 2016 01:23:34 +1000 Subject: No functional changes. Credit gcu This merge doesn't make any functional changes. It's a trivial style fix so that @gregorycu can be dual credited along with shadowninja for PR #4800 --- src/shader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shader.cpp') diff --git a/src/shader.cpp b/src/shader.cpp index 170b0354d..d51c1e308 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -557,7 +557,7 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, } bool enable_shaders = g_settings->getBool("enable_shaders"); - if(!enable_shaders) + if (!enable_shaders) return shaderinfo; video::IVideoDriver* driver = device->getVideoDriver(); -- cgit v1.2.3 From 075833e39368e63e06889f21140f816420e83541 Mon Sep 17 00:00:00 2001 From: Lars Hofhansl Date: Sat, 3 Dec 2016 21:43:25 -0800 Subject: Fog: Make fraction of visible distance at which fog starts configurable Optimise the fetching of global settings 'camera_smoothing', 'cinematic' and 'cinematic_camera_smoothing'. Cache 'cam_smoothing'. --- builtin/settingtypes.txt | 3 ++ client/shaders/nodes_shader/opengl_fragment.glsl | 2 +- .../water_surface_shader/opengl_fragment.glsl | 2 +- client/shaders/wielded_shader/opengl_fragment.glsl | 2 +- minetest.conf.example | 4 +++ src/defaultsettings.cpp | 1 + src/game.cpp | 37 ++++++++++++++++------ src/shader.cpp | 4 +++ 8 files changed, 43 insertions(+), 12 deletions(-) (limited to 'src/shader.cpp') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index b1f31054e..10db4787d 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -529,6 +529,9 @@ ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0 # Enables animation of inventory items. inventory_items_animations (Inventory items animations) bool false +# Fraction of the visible distance at which fog starts to be rendered +fog_start (Fog Start) float 0.4 0.0 0.99 + [**Menus] # Use a cloud animation for the main menu background. diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 149aa2bc5..71ded2b9d 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -19,7 +19,7 @@ bool normalTexturePresent = false; const float e = 2.718281828459; const float BS = 10.0; -const float fogStart = 0.4; +const float fogStart = FOG_START; const float fogShadingParameter = 1 / ( 1 - fogStart); #ifdef ENABLE_TONE_MAPPING diff --git a/client/shaders/water_surface_shader/opengl_fragment.glsl b/client/shaders/water_surface_shader/opengl_fragment.glsl index 4164870c7..c4e78470d 100644 --- a/client/shaders/water_surface_shader/opengl_fragment.glsl +++ b/client/shaders/water_surface_shader/opengl_fragment.glsl @@ -21,7 +21,7 @@ bool texSeamless = false; const float e = 2.718281828459; const float BS = 10.0; -const float fogStart = 0.4; +const float fogStart = FOG_START; const float fogShadingParameter = 1 / ( 1 - fogStart); #ifdef ENABLE_TONE_MAPPING diff --git a/client/shaders/wielded_shader/opengl_fragment.glsl b/client/shaders/wielded_shader/opengl_fragment.glsl index 7c38b749a..ba7a8f12d 100644 --- a/client/shaders/wielded_shader/opengl_fragment.glsl +++ b/client/shaders/wielded_shader/opengl_fragment.glsl @@ -19,7 +19,7 @@ bool texSeamless = false; const float e = 2.718281828459; const float BS = 10.0; -const float fogStart = 0.4; +const float fogStart = FOG_START; const float fogShadingParameter = 1 / ( 1 - fogStart); void get_texture_flags() diff --git a/minetest.conf.example b/minetest.conf.example index 361311ba0..90d7af0a3 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -615,6 +615,10 @@ # type: bool # inventory_items_animations = false +# Fraction of the visible distance at which fog starts to be rendered +# Range 0 - 0.99 +# fog_start = 0.4 + ### Menus # Use a cloud animation for the main menu background. diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 2cb57532d..bd88cf530 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -106,6 +106,7 @@ void set_default_settings(Settings *settings) settings->setDefault("client_unload_unused_data_timeout", "600"); settings->setDefault("client_mapblock_limit", "5000"); settings->setDefault("enable_fog", "true"); + settings->setDefault("fog_start", "0.4"); settings->setDefault("fov", "72"); settings->setDefault("view_bobbing", "true"); settings->setDefault("leaves_style", "fancy"); diff --git a/src/game.cpp b/src/game.cpp index e6d38d0a0..cc6e5a0e3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1825,6 +1825,8 @@ private: f32 m_cache_mouse_sensitivity; f32 m_cache_joystick_frustum_sensitivity; f32 m_repeat_right_click_time; + f32 m_cache_cam_smoothing; + f32 m_cache_fog_start; #ifdef __ANDROID__ bool m_cache_hold_aux1; @@ -1876,6 +1878,12 @@ Game::Game() : &settingChangedCallback, this); g_settings->registerChangedCallback("free_move", &settingChangedCallback, this); + g_settings->registerChangedCallback("cinematic", + &settingChangedCallback, this); + g_settings->registerChangedCallback("cinematic_camera_smoothing", + &settingChangedCallback, this); + g_settings->registerChangedCallback("camera_smoothing", + &settingChangedCallback, this); readSettings(); @@ -1929,6 +1937,12 @@ Game::~Game() &settingChangedCallback, this); g_settings->deregisterChangedCallback("free_move", &settingChangedCallback, this); + g_settings->deregisterChangedCallback("cinematic", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("cinematic_camera_smoothing", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("camera_smoothing", + &settingChangedCallback, this); } bool Game::startup(bool *kill, @@ -2034,16 +2048,10 @@ void Game::run() processUserInput(&flags, &runData, dtime); // Update camera before player movement to avoid camera lag of one frame updateCameraDirection(&cam_view_target, &flags, dtime); - float cam_smoothing = 0; - if (g_settings->getBool("cinematic")) - cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing"); - else - cam_smoothing = 1 - g_settings->getFloat("camera_smoothing"); - cam_smoothing = rangelim(cam_smoothing, 0.01f, 1.0f); cam_view.camera_yaw += (cam_view_target.camera_yaw - - cam_view.camera_yaw) * cam_smoothing; + cam_view.camera_yaw) * m_cache_cam_smoothing; cam_view.camera_pitch += (cam_view_target.camera_pitch - - cam_view.camera_pitch) * cam_smoothing; + cam_view.camera_pitch) * m_cache_cam_smoothing; updatePlayerControl(cam_view); step(&dtime); processClientEvents(&cam_view_target, &runData.damage_flash); @@ -4284,7 +4292,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, driver->setFog( sky->getBgColor(), video::EFT_FOG_LINEAR, - runData->fog_range * 0.4, + runData->fog_range * m_cache_fog_start, runData->fog_range * 1.0, 0.01, false, // pixel fog @@ -4660,7 +4668,18 @@ void Game::readSettings() m_cache_enable_noclip = g_settings->getBool("noclip"); m_cache_enable_free_move = g_settings->getBool("free_move"); + m_cache_fog_start = g_settings->getFloat("fog_start"); + + m_cache_cam_smoothing = 0; + if (g_settings->getBool("cinematic")) + m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing"); + else + m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing"); + + m_cache_fog_start = rangelim(m_cache_fog_start, 0.0f, 0.99f); + m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f); m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0); + } /****************************************************************************/ diff --git a/src/shader.cpp b/src/shader.cpp index d51c1e308..c0ecf738d 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -751,6 +751,10 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, if (g_settings->getBool("tone_mapping")) shaders_header += "#define ENABLE_TONE_MAPPING\n"; + shaders_header += "#define FOG_START "; + shaders_header += ftos(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); + shaders_header += "\n"; + // Call addHighLevelShaderMaterial() or addShaderMaterial() const c8* vertex_program_ptr = 0; const c8* pixel_program_ptr = 0; -- cgit v1.2.3