From ce3ed28403b75d742ec1f239712ea0c63ae6fe87 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 18 Apr 2021 21:44:23 +0100 Subject: [PATCH] Control stomping via settings. --- apps/openmw/mwrender/renderingmanager.cpp | 3 ++ .../modding/settings/groundcover.rst | 54 +++++++++++++++++++ files/settings-default.cfg | 12 +++++ files/shaders/groundcover_vertex.glsl | 33 +++++++++--- 4 files changed, 94 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 16e0a351f..dc5373b0b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -264,9 +264,12 @@ namespace MWRender for (auto itr = lightDefines.begin(); itr != lightDefines.end(); itr++) globalDefines[itr->first] = itr->second; + // Refactor this at some point - most shaders don't care about these defines float groundcoverDistance = (Constants::CellSizeInUnits * std::max(1, Settings::Manager::getInt("distance", "Groundcover")) - 1024) * 0.93; globalDefines["groundcoverFadeStart"] = std::to_string(groundcoverDistance * 0.9f); globalDefines["groundcoverFadeEnd"] = std::to_string(groundcoverDistance); + globalDefines["groundcoverStompMode"] = std::to_string(std::clamp(Settings::Manager::getInt("stomp mode", "Groundcover"), 0, 2)); + globalDefines["groundcoverStompIntensity"] = std::to_string(std::clamp(Settings::Manager::getInt("stomp intensity", "Groundcover"), 0, 2)); // It is unnecessary to stop/start the viewer as no frames are being rendered yet. mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines); diff --git a/docs/source/reference/modding/settings/groundcover.rst b/docs/source/reference/modding/settings/groundcover.rst index f0c37b738..ef97caeec 100644 --- a/docs/source/reference/modding/settings/groundcover.rst +++ b/docs/source/reference/modding/settings/groundcover.rst @@ -54,3 +54,57 @@ chunks near player will have size 4096x4096 game units. Larger chunks reduce CPU Smaller values do an opposite. This setting can only be configured by editing the settings configuration file. + +stomp mode +---------- + +:Type: integer +:Range: 0, 1, 2 +:Default: 2 + +Determines whether grass should respond to the player treading on it. + +.. list-table:: Modes + :header-rows: 1 + * - Mode number + - Meaning + * - 0 + - Grass cannot be trampled. + * - 1 + - The player's XY position is taken into account. + * - 2 + - The player's height above the ground is taken into account, too. + +In MGE XE, which existing grass mods were made for, only the player's XY position was taken into account. +However, presumably due to a bug, jumping straight up would change the XY position, so grass *does* respond to the player jumping. +Levitating above grass in MGE XE still considers it stood-on, which can look bad. +OpenMW's height-aware system ensures grass does not act as if it's being stood on when the player levitates above it, but that means grass rapidly snaps back to its original position when the player jumps out of it. +Therefore, it is not recommended to use MGE XE's intensity constants if this setting is set to 2, i.e. :ref:`stomp intensity` should be 0 or 1 when :ref:`stomp mode` is 2. + +stomp intensity +--------------- + +:Type: integer +:Range: 0, 1, 2 +:Default: 1 + +How far away from the player grass can be before it's unaffected by being trod on, and how far it moves when it is. + +.. list-table:: Presets + :header-rows: 1 + * - Preset number + - Range (Units) + - Distance (Units) + - Description + * - 2 + - 150 + - 60 + - MGE XE levels. Generally excessive/comical, but what existing mods were made with in mind. + * - 1 + - 80 + - 40 + - Reduced levels. Usually looks better. + * - 0 + - 50 + - 20 + - Gentle levels. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 07343b39d..c20820e68 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -1079,3 +1079,15 @@ distance = 1 # A minimum size of groundcover chunk in cells (0.125, 0.25, 0.5, 1.0) min chunk size = 0.5 + +# Whether grass should respond to the player treading on it. +# 0 - Grass cannot be trampled. +# 1 - The player's XY position is taken into account. +# 2 - The player's height above the ground is taken into account, too. +stomp mode = 2 + +# How far away from the player grass can be before it's unaffected by being trod on, and how far it moves when it is. +# 2 - MGE XE levels. Generally excessive, but what existing mods were made with in mind +# 1 - Reduced levels. +# 0 - Gentle levels. +stomp intensity = 1 diff --git a/files/shaders/groundcover_vertex.glsl b/files/shaders/groundcover_vertex.glsl index d7d221e45..8060c2c3d 100644 --- a/files/shaders/groundcover_vertex.glsl +++ b/files/shaders/groundcover_vertex.glsl @@ -46,6 +46,15 @@ uniform mat4 osg_ViewMatrix; uniform float windSpeed; uniform vec3 playerPos; +#if @groundcoverStompMode == 0 +#else + #define STOMP 1 + #if @groundcoverStompMode == 2 + #define STOMP_HEIGHT_SENSITIVE 1 + #endif + #define STOMP_INTENSITY_LEVEL @groundcoverStompIntensity +#endif + vec2 groundcoverDisplacement(in vec3 worldpos, float h) { vec2 windDirection = vec2(1.0); @@ -61,20 +70,28 @@ vec2 groundcoverDisplacement(in vec3 worldpos, float h) harmonics += vec2((1.0 + 0.14*v) * sin(3.0*osg_SimulationTime + worldpos.xy / 500.0)); harmonics += vec2((1.0 + 0.28*v) * sin(5.0*osg_SimulationTime + worldpos.xy / 200.0)); -#if 0 - // akortunov's height adjustment - float d = length(worldpos - footPos.xyz); -#else + vec2 stomp = vec2(0.0); +#if STOMP float d = length(worldpos.xy - footPos.xy); +#if STOMP_INTENSITY_LEVEL == 0 + // Gentle intensity + const float STOMP_RANGE = 50.0; // maximum distance from player that grass is affected by stomping + const float STOMP_DISTANCE = 20.0; // maximum distance stomping can move grass +#elif STOMP_INTENSITY_LEVEL == 1 + // Reduced intensity + const float STOMP_RANGE = 80.0; + const float STOMP_DISTANCE = 40.0; +#elif STOMP_INTENSITY_LEVEL == 2 + // MGE XE intensity + const float STOMP_RANGE = 150.0; + const float STOMP_DISTANCE = 60.0; #endif - vec2 stomp = vec2(0.0); - const float STOMP_RANGE = 150.0; // maximum distance from player that grass is affected by stomping - const float STOMP_DISTANCE = 60.0; // maximum distance stomping can move grass if (d < STOMP_RANGE && d > 0.0) stomp = (STOMP_DISTANCE / d - STOMP_DISTANCE / STOMP_RANGE) * (worldpos.xy - footPos.xy); -#if 1 +#ifdef STOMP_HEIGHT_SENSITIVE stomp *= clamp((worldpos.z - footPos.z) / h, 0.0, 1.0); +#endif #endif return clamp(0.02 * h, 0.0, 1.0) * (harmonics * displace + stomp);