diff --git a/data/base/shaders/vk/pointlights.glsl b/data/base/shaders/vk/pointlights.glsl index c8de86a15b6..12e53389be1 100644 --- a/data/base/shaders/vk/pointlights.glsl +++ b/data/base/shaders/vk/pointlights.glsl @@ -134,7 +134,7 @@ vec4 volumetricLights( vec3 transMittance = vec3(1); -#define STEPS 64 +#define STEPS (WZ_VOLUMETRIC_LIGHTING_ENABLED * 16) for (int i = 0; i < STEPS; i++) { diff --git a/data/base/shaders/vk/tcmask_instanced.frag b/data/base/shaders/vk/tcmask_instanced.frag index 0a540a9fd70..69b09db0d91 100644 --- a/data/base/shaders/vk/tcmask_instanced.frag +++ b/data/base/shaders/vk/tcmask_instanced.frag @@ -376,7 +376,7 @@ void main() fragColour.a = 0.66 + 0.66 * graphicsCycle; } - if (WZ_VOLUMETRIC_LIGHTING_ENABLED == 1) { + if (WZ_VOLUMETRIC_LIGHTING_ENABLED != 0) { vec2 clipSpaceCoord = gl_FragCoord.xy / vec2(viewportWidth, viewportHeight); vec4 volumetric = volumetricLights(clipSpaceCoord, cameraPos.xyz, fragPos, diffuse.xyz); fragColour.xyz = toneMap(fragColour.xyz * volumetric.a + volumetric.xyz); diff --git a/lib/ivis_opengl/gfx_api.h b/lib/ivis_opengl/gfx_api.h index 3a74969c485..a6a6149f18f 100644 --- a/lib/ivis_opengl/gfx_api.h +++ b/lib/ivis_opengl/gfx_api.h @@ -43,6 +43,15 @@ using nonstd::optional; using nonstd::nullopt; + +enum class VOLUMETRIC_LIGHT_LEVEL +{ + disabled, + low, + medium, + high, +}; + namespace gfx_api { // Must be implemented by backend (ex. SDL) @@ -326,7 +335,7 @@ namespace gfx_api uint32_t shadowFilterSize = 5; uint32_t shadowCascadesCount = WZ_MAX_SHADOW_CASCADES; bool isPointLightPerPixelEnabled = false; - bool isVolumetricLightingEnabled = false; + VOLUMETRIC_LIGHT_LEVEL isVolumetricLightingEnabled = VOLUMETRIC_LIGHT_LEVEL::disabled; bool operator==(const lighting_constants& rhs) const { diff --git a/lib/ivis_opengl/gfx_api_vk.cpp b/lib/ivis_opengl/gfx_api_vk.cpp index cea3a54dd0e..8db87691aaa 100644 --- a/lib/ivis_opengl/gfx_api_vk.cpp +++ b/lib/ivis_opengl/gfx_api_vk.cpp @@ -1774,7 +1774,7 @@ VkPSO::VkPSO(vk::Device _dev, appendSpecializationConstant_uint32(4, static_cast(root->shadowConstants.isPointLightPerPixelEnabled)); hasSpecializationConstant_PointLightConstants = true; } - if (shaderInfo.specializationConstant_4_pointLightEnabled) + if (shaderInfo.specializationConstant_5_volumetricEnabled) { appendSpecializationConstant_uint32(5, static_cast(root->shadowConstants.isVolumetricLightingEnabled)); hasSpecializationConstant_VolumetricLightingConstants = true; diff --git a/lib/ivis_opengl/piestate.cpp b/lib/ivis_opengl/piestate.cpp index 2cea47ea60d..4f4ba747c42 100644 --- a/lib/ivis_opengl/piestate.cpp +++ b/lib/ivis_opengl/piestate.cpp @@ -119,7 +119,7 @@ void pie_FreeShaders() //static float fogEnd; // Run from screen.c on init. -bool pie_LoadShaders(uint32_t shadowFilterSize, bool pointLightEnabled, bool volumetricEnabled) +bool pie_LoadShaders(uint32_t shadowFilterSize, bool pointLightEnabled, VOLUMETRIC_LIGHT_LEVEL volumetricEnabled) { // note: actual loading of shaders now occurs in gfx_api diff --git a/lib/ivis_opengl/piestate.h b/lib/ivis_opengl/piestate.h index 42c956525d1..0352cf325f7 100644 --- a/lib/ivis_opengl/piestate.h +++ b/lib/ivis_opengl/piestate.h @@ -82,7 +82,7 @@ const Vector3f& getDefaultSunPosition(); int pie_GetMaxAntialiasing(); -bool pie_LoadShaders(uint32_t shadowFilterSize, bool pointLightEnabled, bool volumetricEnabled); +bool pie_LoadShaders(uint32_t shadowFilterSize, bool pointLightEnabled, VOLUMETRIC_LIGHT_LEVEL volumetricEnabled); void pie_FreeShaders(); namespace pie_internal diff --git a/src/configuration.cpp b/src/configuration.cpp index 061de45d600..8b1bceddde6 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -619,8 +619,8 @@ bool loadConfig() } { - auto value = iniGetBoolOpt("volumetricLighting"); - war_setVolumetricLighting(value.value_or(false)); + auto value = iniGetIntegerOpt("volumetricLighting"); + war_setVolumetricLighting(static_cast(value.value_or(0))); } ActivityManager::instance().endLoadingSettings(); @@ -784,7 +784,7 @@ bool saveConfig() iniSetInteger("shadowFilterSize", (int)war_getShadowFilterSize()); iniSetInteger("shadowMapResolution", (int)war_getShadowMapResolution()); iniSetBool("pointLightsPerpixel", war_getPointLightPerPixelLighting()); - iniSetBool("volumetricLighting", war_getVolumetricLighting()); + iniSetInteger("volumetricLighting", static_cast(war_getVolumetricLighting())); iniSetInteger("configVersion", CURRCONFVERSION); // write out ini file changes diff --git a/src/frontend.cpp b/src/frontend.cpp index 90d1f8d8e1e..6201dab361b 100644 --- a/src/frontend.cpp +++ b/src/frontend.cpp @@ -860,7 +860,14 @@ char const* graphicsOptionsLightingString() char const* graphicsOptionsVolumetricLightingString() { - return war_getVolumetricLighting() ? _("On") : _("Off"); + switch (war_getVolumetricLighting()) + { + case VOLUMETRIC_LIGHT_LEVEL::low: return _("Low"); + case VOLUMETRIC_LIGHT_LEVEL::medium: return _("Medium"); + case VOLUMETRIC_LIGHT_LEVEL::high: return _("High"); + } + + return _("Disabled"); } char const *graphicsOptionsFogString() @@ -1309,7 +1316,9 @@ bool runGraphicsOptionsMenu() case FRONTEND_VOLUMETRIC_LIGHTING: case FRONTEND_VOLUMETRIC_LIGHTING_R: { - war_setVolumetricLighting(!war_getVolumetricLighting()); + auto previousValue = static_cast(war_getVolumetricLighting()); + auto newValue = previousValue + 1 % 4; + war_setVolumetricLighting(static_cast(newValue)); widgSetString(psWScreen, FRONTEND_VOLUMETRIC_LIGHTING_R, graphicsOptionsVolumetricLightingString()); break; } diff --git a/src/warzoneconfig.cpp b/src/warzoneconfig.cpp index ce039380d6c..a9f1d51e24a 100644 --- a/src/warzoneconfig.cpp +++ b/src/warzoneconfig.cpp @@ -90,7 +90,7 @@ struct WARZONE_GLOBALS uint32_t shadowFilterSize = 5; uint32_t shadowMapResolution = 0; // this defaults to 0, which causes the gfx backend to figure out a recommended default based on the system properties bool pointLightLighting = false; - bool volumetricLighting = false; + VOLUMETRIC_LIGHT_LEVEL volumetricLighting = VOLUMETRIC_LIGHT_LEVEL::disabled; // groups UI bool groupsMenuEnabled = true; @@ -657,7 +657,7 @@ bool war_getPointLightPerPixelLighting() return warGlobs.pointLightLighting; } -bool war_getVolumetricLighting() +VOLUMETRIC_LIGHT_LEVEL war_getVolumetricLighting() { return warGlobs.volumetricLighting; } @@ -667,7 +667,7 @@ void war_setPointLightPerPixelLighting(bool perPixelEnabled) warGlobs.pointLightLighting = perPixelEnabled; } -void war_setVolumetricLighting(bool volumetricEnabled) +void war_setVolumetricLighting(VOLUMETRIC_LIGHT_LEVEL volumetricEnabled) { warGlobs.volumetricLighting = volumetricEnabled; } diff --git a/src/warzoneconfig.h b/src/warzoneconfig.h index c359ddf33da..f0df056f045 100644 --- a/src/warzoneconfig.h +++ b/src/warzoneconfig.h @@ -59,6 +59,8 @@ enum class JS_BACKEND num_backends // Must be last! }; +enum class VOLUMETRIC_LIGHT_LEVEL; + bool js_backend_from_str(const char *str, JS_BACKEND &output_backend); std::string to_string(JS_BACKEND backend); @@ -165,8 +167,8 @@ void war_setShadowMapResolution(uint32_t resolution); bool war_getPointLightPerPixelLighting(); void war_setPointLightPerPixelLighting(bool perPixelEnabled); -bool war_getVolumetricLighting(); -void war_setVolumetricLighting(bool enabled); +VOLUMETRIC_LIGHT_LEVEL war_getVolumetricLighting(); +void war_setVolumetricLighting(VOLUMETRIC_LIGHT_LEVEL enabled); bool war_getGroupsMenuEnabled(); void war_setGroupsMenuEnabled(bool enabled);