Agrarsense
AgrarsenseSettings.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
7
15
16#include "Misc/CommandLine.h"
17#include "GenericPlatform/GenericPlatformMisc.h"
18#include "Kismet/GameplayStatics.h"
19#include "GameFramework/GameUserSettings.h"
20#include "Misc/CoreDelegates.h"
21#include "Misc/Parse.h"
22#include "Misc/App.h"
23#include "Engine/Engine.h"
24#include "Engine/GameViewportClient.h"
25#include "UObject/ObjectPtr.h"
26#include "LandscapeSubsystem.h"
27#include "Engine/World.h"
28#include "Engine/GameInstance.h"
29#include "TimerManager.h"
30
31#include "RHI.h"
32#include "RHIDefinitions.h"
33
36
38{
39}
40
41void UAgrarsenseSettings::Setup(UWorld* World)
42{
43#if WITH_EDITOR
44 // In case the simulator was shutdown when it was paused,
45 // reset this static variable
47#endif
48
49 CurrentWorld = World;
50
51 UWorld* GameWorld = CurrentWorld.Get();
52
53 CurrentMapName = GameWorld->GetMapName().ToLower();
54 IsMainMenu = CurrentMapName.Contains("mainmenu");
55
56 if (GameWorld)
57 {
58 // Prioritize grass creation
59 // This allows turning grass on faster if it was turned off.
60 ULandscapeSubsystem* LandscapeSubsystem = CurrentWorld->GetSubsystem<ULandscapeSubsystem>();
61 if (LandscapeSubsystem)
62 {
63 LandscapeSubsystem->PrioritizeGrassCreation(true);
64 }
65 }
66
67 // Apply Graphics and Simulation settings when Simulator is started
68 ApplySettings(true);
69
70 // Apply few console commands. One time setup.
71 if (GEngine && World)
72 {
73 GEngine->Exec(World, TEXT("g.TimeoutForBlockOnRenderFence 600000"));
74 GEngine->Exec(World, TEXT("r.Streaming.PoolSize 0"));
75
76 // Disable application starting to throttle performance if Window loses focus
77 GEngine->Exec(World, TEXT("t.IdleWhenNotForeground 0"));
78 }
79
80#if UE_BUILD_SHIPPING
81 // In Shipping mode check for Fullscreen and WindowedFullscreen launch args,
82 // Otherwise set window to windowed by default.
83 if (FParse::Param(FCommandLine::Get(), TEXT("Fullscreen")))
84 {
85 SetWindowMode(EWindowMode::Type::Fullscreen);
86 }
87 else if (FParse::Param(FCommandLine::Get(), TEXT("WindowedFullscreen")))
88 {
89 SetWindowMode(EWindowMode::Type::WindowedFullscreen);
90 }
91 else
92 {
93 SetWindowMode(EWindowMode::Type::Windowed);
94 }
95#endif
96}
97
99{
100 Super::PostInitProperties();
101
102#if UE_BUILD_SHIPPING || UE_BUILD_DEVELOPMENT
104 {
105 SaveConfig();
106 }
107#endif
108}
109
111{
112 return Cast<UAgrarsenseSettings>(UGameUserSettings::GetGameUserSettings());
113}
114
116{
117 Super::LoadSettings(bForceReload);
118}
119
120void UAgrarsenseSettings::ApplySettings(bool bCheckForCommandLineOverrides)
121{
122 Super::ApplySettings(bCheckForCommandLineOverrides);
123
126}
127
129{
130 bool SettingsWereChanged = false;
131
132 // Check -map= launch argument
133 FString AntiAliasingString;
134 if (FParse::Value(FCommandLine::Get(), TEXT("-antialiasing="), AntiAliasingString))
135 {
136 // Convert incoming string to int and then EAntiAliasing enum
137 int32 AntiAliasingInt;
138 if (AntiAliasingString.IsNumeric())
139 {
140 AntiAliasingInt = FCString::Atoi(*AntiAliasingString);
141 EAntiAliasing NewAntiAliasingMethod = static_cast<EAntiAliasing>(AntiAliasingInt);
142 GraphicsSettings.AntiAliasingMethod = NewAntiAliasingMethod;
143 SettingsWereChanged = true;
144 }
145 }
146
147 // Check -no-world-rendering launch argument
148 if (FParse::Param(FCommandLine::Get(), TEXT("-no-spectator-rendering")))
149 {
151 SettingsWereChanged = true;
152 }
153
154 // Check -start-camerawindows-minimized launch argument
155 if (FParse::Param(FCommandLine::Get(), TEXT("-start-camerawindows-minimized")))
156 {
158 SettingsWereChanged = true;
159 }
160
161 // Check -quality-level= launch argument
162 FString QualityLevelString;
163 if (FParse::Value(FCommandLine::Get(), TEXT("-quality-level="), QualityLevelString))
164 {
166 SettingsWereChanged = true;
167 }
168
169 return SettingsWereChanged;
170}
171
173{
174 return FPlatformMisc::NumberOfWorkerThreadsToSpawn();
175}
176
177FString UAgrarsenseSettings::GetConsoleVariableValueString(const FString& VariableName) const
178{
179 IConsoleVariable* ConsoleVariable = IConsoleManager::Get().FindConsoleVariable(*VariableName);
180 if (ConsoleVariable)
181 {
182 FString VariableValue = ConsoleVariable->GetString();
183 return VariableValue;
184 }
185 else
186 {
187 return FString();
188 }
189}
190
192{
193 GraphicsSettings = NewSettings;
194
201}
202
203void UAgrarsenseSettings::SetWindowMode(EWindowMode::Type WindowType)
204{
205 if (GEngine)
206 {
207 UGameUserSettings* UserSettings = GEngine->GetGameUserSettings();
208 if (UserSettings)
209 {
210 UserSettings->SetFullscreenMode(WindowType);
211 UserSettings->ApplySettings(false);
212 }
213 }
214}
215
217{
218 SimulationSettings = NewSettings;
219
224}
225
227{
229}
230
232{
233 if (GraphicsSettings.RenderGrass == Visible)
234 {
235 return;
236 }
237
238 UWorld* World = CurrentWorld.Get();
239
240 if (!GEngine || !World)
241 {
242 return;
243 }
244
246
248 {
249 GEngine->Exec(World, TEXT("grass.enable 0"));
250 GEngine->Exec(World, TEXT("grass.FlushCache"));
251 }
252 else
253 {
254 GEngine->Exec(World, TEXT("grass.enable 1"));
255 }
256
258}
259
261{
263}
264
266{
267 if (GraphicsSettings.ShadowCSMCaching == CacheShadowCSM)
268 {
269 return;
270 }
271
272 UWorld* World = CurrentWorld.Get();
273 if (GEngine && World)
274 {
275 GraphicsSettings.ShadowCSMCaching = CacheShadowCSM;
276
278 {
279 GEngine->Exec(World, TEXT("r.Shadow.CSMCaching 1"));
280 }
281 else
282 {
283 GEngine->Exec(World, TEXT("r.Shadow.CSMCaching 0"));
284 }
285
287 }
288}
289
291{
292 UWorld* World = CurrentWorld.Get();
293
294 if (World)
295 {
297 if (InstanceRenderer)
298 {
299 InstanceRenderer->SetInstancedRendering(Visible);
300 }
301 }
302}
303
305{
306 GraphicsSettings.WorldPositionOffsetDistance = WorldPositionOffsetDistance;
308}
309
311{
312 UWorld* World = CurrentWorld.Get();
313 if (GEngine && World)
314 {
315 MaxPixelsPerEdge = FMath::Clamp(MaxPixelsPerEdge, 0.1f, 10.0f);
316
317 FString Command = FString::Printf(TEXT("r.Nanite.MaxPixelsPerEdge %f"), MaxPixelsPerEdge);
318 GEngine->Exec(World, *Command);
319
320 GraphicsSettings.NaniteMaxPixelsPerEdge = MaxPixelsPerEdge;
322 }
323}
324
325void UAgrarsenseSettings::SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior Behaviour)
326{
328 {
331 }
332}
333
335{
336 FString BehaviourStringToLower = BehaviourString.ToLower();
337
338 if (BehaviourStringToLower == "auto")
339 {
340 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Auto);
341 }
342 else if (BehaviourStringToLower == "rigid")
343 {
344 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Rigid);
345 }
346 else if (BehaviourStringToLower == "always")
347 {
348 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Always);
349 }
350 else if (BehaviourStringToLower == "static")
351 {
352 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Static);
353 }
354}
355
357{
359}
360
362{
364}
365
366EShadowCacheInvalidationBehavior UAgrarsenseSettings::GetShadowCacheInvalidationBehavior() const
367{
369}
370
372{
374}
375
377{
379}
380
381void UAgrarsenseSettings::SetRenderCustomDepthPass(bool RenderCustomDepthPass)
382{
383 UWorld* World = CurrentWorld.Get();
384 if (GEngine || World)
385 {
386 RenderCustomDepth = RenderCustomDepthPass;
387 if (RenderCustomDepthPass)
388 {
389 // Note. calling this runtime will cause niagara particles to stop working correctly.
390 GEngine->Exec(World, TEXT("r.CustomDepth 3"));
391 }
392 else
393 {
394 GEngine->Exec(World, TEXT("r.CustomDepth 0"));
395 }
396 }
397}
398
399void UAgrarsenseSettings::SetUseVirtualShadowMaps(bool UseVirtualShadowMaps)
400{
401 UWorld* World = CurrentWorld.Get();
402 if (GEngine || World)
403 {
404 GraphicsSettings.UseVirtualShadowMaps = UseVirtualShadowMaps;
405
407 {
408 GEngine->Exec(World, TEXT("r.Shadow.Virtual.Enable 1"));
409 }
410 else
411 {
412 GEngine->Exec(World, TEXT("r.Shadow.Virtual.Enable 0"));
413 }
414
416 }
417}
418
420{
422}
423
425{
426 return RenderCustomDepth;
427}
428
430{
432}
433
435{
436
437 UWorld* World = CurrentWorld.Get();
438
439 if (!GEngine || !World)
440 {
441 return;
442 }
443
444 GraphicsSettings.AntiAliasingMethod = AntiAliasingMethod;
445
446 FString ExecCommand;
447 switch (AntiAliasingMethod)
448 {
450 ExecCommand = TEXT("r.AntiAliasingMethod 0");
451 break;
452
454 ExecCommand = TEXT("r.AntiAliasingMethod 1");
455 break;
456
458 ExecCommand = TEXT("r.AntiAliasingMethod 2");
459 break;
460
461 // MSAA ("r.AntiAliasingMethod 3) is not supported on Deferred rendering
462
464 ExecCommand = TEXT("r.AntiAliasingMethod 4");
465 break;
466
467 default:
468 return;
469 }
470
471 GEngine->Exec(World, *ExecCommand);
472
474}
475
476void UAgrarsenseSettings::SetAntiAliasingMethodFromString(const FString& AntiAliasingMethodString)
477{
478 EAntiAliasing NewMethod = UEnumUtilities::ConvertStringToAntiAliasingMethod(AntiAliasingMethodString);
479 SetAntiAliasingMethod(NewMethod);
480}
481
483{
484 if (GEngine && GEngine->GameViewport)
485 {
486 GEngine->GameViewport->bDisableWorldRendering = !enabled;
488
489 FString msg = FString::Printf(TEXT("World rendering: %s"), enabled ? TEXT("On") : TEXT("Off"));
491
493 }
494}
495
497{
498 GraphicsSettings.QualityLevel = newQualityLevel;
499
501 {
504 break;
505
508 break;
509
512 break;
513
516 break;
517 }
518
520 FString Msg = FString::Printf(TEXT("Graphics settings: %s"), *QualityLevelString);
522
524}
525
526void UAgrarsenseSettings::SetQualityLevelFromString(const FString& QualityLevelString)
527{
529}
530
532{
533 return GetFrameRateLimit();
534}
535
537{
538 SetFrameRateLimit(NewTargetFrameRate);
539 ApplySettings(false);
540}
541
543{
544 UWorld* World = CurrentWorld.Get();
545
546 if (!World)
547 {
549 }
550
551 return UGameplayStatics::GetGlobalTimeDilation(World);
552}
553
555{
556 UWorld* World = CurrentWorld.Get();
557 if (!World)
558 {
559 return;
560 }
561
562 SimulationSettings.TimeDilation = TimeDilation;
563 UGameplayStatics::SetGlobalTimeDilation(World, TimeDilation);
564
565 FString msg = FString::Printf(TEXT("Global time dilation: %f"), TimeDilation);
567}
568
570{
571 UWorld* World = CurrentWorld.Get();
572 if (!World)
573 {
574 return;
575 }
576
578 if (IsValid(Spectator))
579 {
580 Spectator->SetMaxSpeed(MaxSpeed);
582 }
583}
584
586{
587 UWorld* World = CurrentWorld.Get();
588 if (!World)
589 {
590 return;
591 }
592
594
595 if (IsValid(Spectator))
596 {
597 Spectator->SetNiagaraComponentVisibility(Show);
599 }
600}
601
603{
604 UWorld* World = CurrentWorld.Get();
606 {
607 UGameplayStatics::SetGlobalTimeDilation(World, 0.0f);
608 UGameplayStatics::SetGamePaused(World, true);
610
611 SimulatorLog::Log("Simulator paused");
612 }
613}
614
616{
617 UWorld* World = CurrentWorld.Get();
619 {
620 UGameplayStatics::SetGlobalTimeDilation(World, SimulationSettings.TimeDilation);
621 UGameplayStatics::SetGamePaused(World, false);
623
624 SimulatorLog::Log("Simulator unpaused");
625 }
626}
627
629{
631 {
632 return;
633 }
634
635 // Subscribe to Unreal Engine end of frame callback
636 EndOfFrameHandle = FCoreDelegates::OnEndFrame.AddLambda([this]()
637 {
638 // After receiving the event, unsubcribe from the event and pause the simulation.
639 if (IsValid(this))
640 {
641 if (EndOfFrameHandle.IsValid())
642 {
643 FCoreDelegates::OnEndFrame.Remove(EndOfFrameHandle);
644 EndOfFrameHandle.Reset();
645 }
646
648 }
649 });
650}
651
652void UAgrarsenseSettings::AdvanceFrameCount(int32 FramesToAdvance)
653{
654 if (FramesToAdvance == 0)
655 {
656 return;
657 }
658
659 if (AdvanceFramesHandle.IsValid())
660 {
661 // Already running this, return
662 return;
663 }
664
665 if (EndOfFrameHandle.IsValid())
666 {
667 // If PauseSimulationEndOfThisFrame was called, unsubribe
668 FCoreDelegates::OnEndFrame.Remove(EndOfFrameHandle);
669 EndOfFrameHandle.Reset();
670 }
671
672 // Unpause simulation now
674
675 FrameCount = 0;
676
677 // Subscribe to Unreal Engine end of frame callback
678 AdvanceFramesHandle = FCoreDelegates::OnEndFrame.AddLambda([this, FramesToAdvance]()
679 {
680 ++FrameCount;
681 if (FrameCount == FramesToAdvance)
682 {
683 // After given number of frames,
684 // unsubscribe from the event and pause simulation again at the end of that frame
685 if (IsValid(this))
686 {
687 FCoreDelegates::OnEndFrame.Remove(AdvanceFramesHandle);
688 AdvanceFramesHandle.Reset();
689 FrameCount = 0;
690
692 }
693 }
694 });
695}
696
697void UAgrarsenseSettings::AdvanceTime(float TimeToAdvance)
698{
699 UWorld* World = CurrentWorld.Get();
700 if (!World)
701 {
702 return;
703 }
704
705 // Unpause simulation now
707
708 // Pause simulation again after TimeToAdvance
709 FTimerHandle AdvanceTimeTimer;
710 World->GetTimerManager().SetTimer(AdvanceTimeTimer, FTimerDelegate::CreateLambda([this]
711 {
712 if (IsValid(this))
713 {
715 }
716
717 }), TimeToAdvance, false);
718}
719
721{
722 // Make the map name to lower
723 // This is because ROSCommands.cpp uses this and all the messages are in lower case.
724 MapName = MapName.ToLower();
725
726 bool FoundMap = false;
727 for (int32 i = 0; i < MapNames.Num(); i++)
728 {
729 if (MapName == MapNames[i])
730 {
731 FoundMap = true;
732 FString msg = FString::Printf(TEXT("Changing map to: %s"), *MapName);
734
736 break;
737 }
738 }
739
740 if (!FoundMap)
741 {
742 FString msg = FString::Printf(TEXT("Couldn't find map: %s"), *MapName);
744 }
745}
746
748{
749 UWorld* World = CurrentWorld.Get();
750 if (World)
751 {
752 UGameplayStatics::OpenLevel(World, *Path, TRAVEL_Absolute);
753 }
754}
755
757{
759 {
762 }
763 else
764 {
765 SimulatorLog::Log("Graphics settings: Ray tracing not supported on this hardware.");
766 }
767}
768
770{
771 bool RayTracingSupported = false;
772
773 // Check if the hardware supports ray tracing
774 IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.RayTracing"));
775 if (CVar && CVar->GetInt() > 0 && GRHISupportsRayTracing)
776 {
777 RayTracingSupported = true;
778 }
779
780 return RayTracingSupported;
781}
782
784{
785 UWorld* World = CurrentWorld.Get();
786 if (!World || !GEngine)
787 {
788 return;
789 }
790
791
792#if (ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION == 6)
793 // Due to UE 5.6 bug where ISM nanite proxies with WPO enabled cause shadows not working properly
794 GEngine->Exec(World, TEXT("r.RayTracing.Geometry.NaniteProxies.WPO 0"));
795#endif
796
797 GEngine->Exec(World, TEXT("r.RayTracing 1"));
798 GEngine->Exec(World, TEXT("r.Lumen.HardwareRayTracing 1")); // Enable lumen raytracing
799 GEngine->Exec(World, TEXT("r.RayTracing.Geometry 1")); // Enable ray tracing geometry
800 GEngine->Exec(World, TEXT("r.RayTracing.Reflections 1")); // Enable ray tracing reflections
801 GEngine->Exec(World, TEXT("r.RayTracing.AmbientOcclusion 1")); // Enable ray tracing ambient occlusion
802 GEngine->Exec(World, TEXT("r.RayTracing.GlobalIllumination 1")); // Enable ray tracing global illumination
803 GEngine->Exec(World, TEXT("r.RayTracing.Translucency 1")); // Enable ray tracing translucency
804 GEngine->Exec(World, TEXT("r.RayTracing.SkyLight 1")); // Enable ray tracing sky light
805
806 // Couldn't get Nanite trees with WPO to work with Raytracing
807 //GEngine->Exec(World, TEXT("r.RayTracing.Shadows 1")); // Enable ray tracing shadows
808 //GEngine->Exec(World, TEXT("r.RayTracing.Shadows.SoftShadows 1"));
809 //GEngine->Exec(World, TEXT("r.RayTracing.Shadows.SamplesPerPixel 4"));
810
811 GEngine->Exec(World, TEXT("r.RayTracing.Reflections.MaxRoughness 1.0")); // Enable reflections on all surfaces
812 GEngine->Exec(World, TEXT("r.RayTracing.Reflections.Shadows 1")); // Enable ray-traced shadows in reflections
813 GEngine->Exec(World, TEXT("r.RayTracing.Reflections.SortTiles 1")); // Optimized tile sorting for performance
814 GEngine->Exec(World, TEXT("r.RayTracing.GlobalIllumination.Quality 4")); // Increase RT GI quality (0-4)
815 GEngine->Exec(World, TEXT("r.RayTracing.GlobalIllumination.SamplesPerPixel 4")); // Improve GI smoothness
816
817 GEngine->Exec(World, TEXT("r.Lumen.Reflections 1")); // Enable Lumen reflections
818 GEngine->Exec(World, TEXT("r.Lumen.ScreenProbeGather.ScreenTraces 1")); // Improve Lumen probe accuracy
819
820 GEngine->Exec(World, TEXT("r.RayTracing.Denoiser 1")); // Enable denoiser
821 GEngine->Exec(World, TEXT("r.RayTracing.Denoiser.TemporalAccumulation 1")); // Temporal stability
822 GEngine->Exec(World, TEXT("r.RayTracing.Denoiser.ReuseRadiance 1")); // Improves light reuse
823}
824
826{
827 UWorld* World = CurrentWorld.Get();
828 if (!World || !GEngine)
829 {
830 return;
831 }
832
833#if (ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION == 6)
834 GEngine->Exec(World, TEXT("r.RayTracing.Geometry.NaniteProxies.WPO 1"));
835#endif
836
837 GEngine->Exec(World, TEXT("r.RayTracing 0"));
838 GEngine->Exec(World, TEXT("r.RayTracing.Denoiser 0"));
839 GEngine->Exec(World, TEXT("r.Lumen.HardwareRayTracing 0"));
840 GEngine->Exec(World, TEXT("r.RayTracing.Geometry 0"));
841 GEngine->Exec(World, TEXT("r.RayTracing.Reflections 0"));
842 GEngine->Exec(World, TEXT("r.RayTracing.AmbientOcclusion 0"));
843 GEngine->Exec(World, TEXT("r.RayTracing.GlobalIllumination 0"));
844 GEngine->Exec(World, TEXT("r.RayTracing.Translucency 0"));
845 GEngine->Exec(World, TEXT("r.RayTracing.SkyLight 0"));
846 GEngine->Exec(World, TEXT("r.RayTracing.Shadows 0"));
847}
848
850{
851 UWorld* World = CurrentWorld.Get();
852 if (!World || !GEngine)
853 {
854 return;
855 }
856
858
859 // https://dev.epicgames.com/documentation/en-us/unreal-engine/scalability-reference-for-unreal-engine?application_version=5.3
860 GEngine->Exec(World, TEXT("sg.PostProcessQuality 3"));
861 GEngine->Exec(World, TEXT("sg.ShadowQuality 3"));
862 GEngine->Exec(World, TEXT("sg.TextureQuality 4"));
863 GEngine->Exec(World, TEXT("sg.EffectsQuality 4"));
864 GEngine->Exec(World, TEXT("sg.FoliageQuality 4"));
865
866 GEngine->Exec(World, TEXT("r.MinScreenRadiusForLights 0.03"));
867 GEngine->Exec(World, TEXT("r.SeparateTranslucency 1"));
868 GEngine->Exec(World, TEXT("r.DepthOfFieldQuality 2"));
869 GEngine->Exec(World, TEXT("r.TranslucencyVolumeBlur 1"));
870 GEngine->Exec(World, TEXT("r.TranslucencyLightingVolumeDim 64"));
871 GEngine->Exec(World, TEXT("r.MaxAnisotropy 8"));
872 GEngine->Exec(World, TEXT("r.LensFlareQuality 2"));
873 GEngine->Exec(World, TEXT("r.SceneColorFringeQuality 1"));
874 GEngine->Exec(World, TEXT("r.FastBlurThreshold 7"));
875 GEngine->Exec(World, TEXT("r.EarlyZPassMovable 1"));
876 GEngine->Exec(World, TEXT("r.ShadowQuality 5"));
877 GEngine->Exec(World, TEXT("r.TranslucentLightingVolume 1"));
878 GEngine->Exec(World, TEXT("r.LightShaftDownSampleFactor 2"));
879 GEngine->Exec(World, TEXT("r.DetailMode 2"));
880 GEngine->Exec(World, TEXT("foliage.DensityScale 1"));
881 GEngine->Exec(World, TEXT("grass.DensityScale 1"));
882 GEngine->Exec(World, TEXT("r.Streaming.PoolSize 0 "));
883 GEngine->Exec(World, TEXT("r.Shadow.RadiusThreshold 0.00"));
884
885 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Auto);
886}
887
889{
890 UWorld* World = CurrentWorld.Get();
891 if (!World || !GEngine)
892 {
893 return;
894 }
895
897
898 GEngine->Exec(World, TEXT("sg.PostProcessQuality 3"));
899 GEngine->Exec(World, TEXT("sg.TextureQuality 3"));
900 GEngine->Exec(World, TEXT("sg.EffectsQuality 3"));
901 GEngine->Exec(World, TEXT("sg.FoliageQuality 3"));
902
903 GEngine->Exec(World, TEXT("r.MinScreenRadiusForLights 0.03"));
904 GEngine->Exec(World, TEXT("r.SeparateTranslucency 1"));
905 GEngine->Exec(World, TEXT("r.DepthOfFieldQuality 2"));
906 GEngine->Exec(World, TEXT("r.TranslucencyVolumeBlur 1"));
907 GEngine->Exec(World, TEXT("r.TranslucencyLightingVolumeDim 64"));
908 GEngine->Exec(World, TEXT("r.MaxAnisotropy 8"));
909 GEngine->Exec(World, TEXT("r.LensFlareQuality 2"));
910 GEngine->Exec(World, TEXT("r.SceneColorFringeQuality 1"));
911 GEngine->Exec(World, TEXT("r.FastBlurThreshold 7"));
912 GEngine->Exec(World, TEXT("r.EarlyZPassMovable 1"));
913 GEngine->Exec(World, TEXT("r.ShadowQuality 3"));
914 GEngine->Exec(World, TEXT("r.TranslucentLightingVolume 1"));
915 GEngine->Exec(World, TEXT("r.LightShaftDownSampleFactor 2"));
916 GEngine->Exec(World, TEXT("r.DetailMode 2"));
917 GEngine->Exec(World, TEXT("r.BloomQuality 4"));
918 GEngine->Exec(World, TEXT("foliage.DensityScale 1"));
919 GEngine->Exec(World, TEXT("grass.DensityScale 1"));
920 GEngine->Exec(World, TEXT("r.Streaming.PoolSize 0 "));
921 GEngine->Exec(World, TEXT("r.Shadow.RadiusThreshold 0.01"));
922
923 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Rigid);
924}
925
927{
928 UWorld* World = CurrentWorld.Get();
929 if (!World || !GEngine)
930 {
931 return;
932 }
933
935
936 GEngine->Exec(World, TEXT("sg.PostProcessQuality 0"));
937 GEngine->Exec(World, TEXT("sg.ShadowQuality 0"));
938 GEngine->Exec(World, TEXT("sg.TextureQuality 0"));
939 GEngine->Exec(World, TEXT("sg.EffectsQuality 0"));
940 GEngine->Exec(World, TEXT("sg.FoliageQuality 0"));
941
942 GEngine->Exec(World, TEXT("r.DefaultFeature.MotionBlur 0"));
943 GEngine->Exec(World, TEXT("r.DefaultFeature.Bloom 0"));
944 GEngine->Exec(World, TEXT("r.DefaultFeature.AmbientOcclusion 0"));
945 GEngine->Exec(World, TEXT("r.DefaultFeature.AmbientOcclusionStaticFraction 0"));
946 GEngine->Exec(World, TEXT("r.HZBOcclusion 0"));
947 GEngine->Exec(World, TEXT("r.MinScreenRadiusForLights 0.01"));
948 GEngine->Exec(World, TEXT("r.SeparateTranslucency 0"));
949 GEngine->Exec(World, TEXT("r.FinishCurrentFrame 0"));
950 GEngine->Exec(World, TEXT("r.MotionBlurQuality 0"));
951 GEngine->Exec(World, TEXT("r.BloomQuality 1"));
952 GEngine->Exec(World, TEXT("r.DepthOfFieldQuality 0"));
953 GEngine->Exec(World, TEXT("r.TranslucencyVolumeBlur 0"));
954 GEngine->Exec(World, TEXT("r.TranslucencyLightingVolumeDim 4"));
955 GEngine->Exec(World, TEXT("r.MaxAnisotropy 4"));
956 GEngine->Exec(World, TEXT("r.LensFlareQuality 0"));
957 GEngine->Exec(World, TEXT("r.SceneColorFringeQuality 0"));
958 GEngine->Exec(World, TEXT("r.FastBlurThreshold 0"));
959 GEngine->Exec(World, TEXT("r.SSR 0"));
960 GEngine->Exec(World, TEXT("r.EarlyZPassMovable 1"));
961 GEngine->Exec(World, TEXT("r.TranslucentLightingVolume 0"));
962 GEngine->Exec(World, TEXT("r.LightShaftDownSampleFactor 4"));
963 GEngine->Exec(World, TEXT("r.OcclusionQueryLocation 1"));
964 GEngine->Exec(World, TEXT("foliage.DensityScale 0"));
965 GEngine->Exec(World, TEXT("grass.DensityScale 0"));
966 GEngine->Exec(World, TEXT("r.Streaming.PoolSize 0 "));
967
968 SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior::Rigid);
969}
EAntiAliasing
Definition: AntiAliasing.h:15
EQualityLevel
Definition: QualityLevel.h:16
void SetMaxSpeed(float MaxSpeed=1500.0f)
Definition: Spectator.cpp:222
bool IsNiagaraComponentVisible()
Definition: Spectator.h:102
float GetMaxSpeed()
Definition: Spectator.cpp:231
void SetNiagaraComponentVisibility(bool Visible)
Definition: Spectator.cpp:214
static void Log(const FString &Message, bool LogToTextFile=true, bool LogToROS=true)
void ApplySettings(bool bCheckForCommandLineOverrides) override
EAntiAliasing GetAntiAliasingMethod() const
void SetStartWindowInitiallyMinimized(bool Minimized)
int32 GetGlobalTargetFrameRate() const
void SetQualityLevelFromString(const FString &QualityLevelString)
EShadowCacheInvalidationBehavior GetShadowCacheInvalidationBehavior() const
void SetSpectatorMaxSpeed(float MaxSpeed)
bool GetIsUsingVirtualShadowMaps() const
int32 GetWorldPositionOffsetRenderDistance() const
void SetShowSpectatorRainAndSnowfall(bool Show)
bool GetStartWindowInitiallyMinimized() const
FDelegateHandle AdvanceFramesHandle
FDelegateHandle EndOfFrameHandle
void SetSimulationSettings(FGlobalSimulationSettings NewSettings)
void AdvanceTime(float TimeToAdvance)
void ChangeMapByName(FString MapName)
void AdvanceFrameCount(int32 FramesToAdvance)
FGraphicsSettingsDelegate OnGraphicsSettingsChanged
void SetAntiAliasingMethod(EAntiAliasing AntiAliasingMethod)
const TArray< FString > MapPaths
void SetInstancedRenderingVisibility(bool Visible)
virtual void PostInitProperties() override
float GetGlobalTimeDilation() const
void SetShadowCSMCache(bool CacheShadowCSM)
void SetGlobalTargetFrameRate(int32 NewTargetFrameRate)
void SetAntiAliasingMethodFromString(const FString &AntiAliasingMethodString)
FGlobalSimulationSettings SimulationSettings
void SetUseVirtualShadowMaps(bool UseVirtualShadowMaps)
void SetGraphicsSettings(FGlobalGraphicsSettings NewSettings)
TWeakObjectPtr< UWorld > CurrentWorld
void LoadSettings(bool bForceReload=false) override
void SetQualityLevel(EQualityLevel newQualityLevel)
void Setup(UWorld *World)
int32 GetNumberOfWorkerThreads() const
float GetNaniteMaxPixelsPerEdge() const
void SetGlobalTimeDilation(float TimeDilation)
static FString CurrentMapName
void SetWindowMode(EWindowMode::Type WindowType)
void SetRenderCustomDepthPass(bool RenderCustomDepthPass)
bool GetIsRenderingCustomDepthPass() const
void SetGrassVisibility(bool Visible)
void SetShadowCacheInvalidationBehaviorFromString(const FString &BehaviourString)
void SetShadowCacheInvalidationBehavior(EShadowCacheInvalidationBehavior Behaviour=EShadowCacheInvalidationBehavior::Rigid)
void ChangeMapByMapPath(const FString &Path)
FString GetConsoleVariableValueString(const FString &VariableName) const
static UAgrarsenseSettings * GetAgrarsenseSettings()
void SetWorldPositionOffsetRenderDistance(int32 WorldPositionOffsetDistance)
FGlobalGraphicsSettings GraphicsSettings
const TArray< FString > MapNames
void SetWorldRendering(bool enabled)
void SetNaniteMaxPixelsPerEdge(float MaxPixelsPerEdge=1.0f)
bool IsRaytracingSupported() const
static ASpectator * GetSpectator(const UObject *WorldContextObject)
static AInstancedRendererManager * GetInstancedRenderer(const UObject *WorldContextObject)
static FString ConvertQualityLevelToString(EQualityLevel QualityLevel)
static EQualityLevel ConvertStringToQualityLevel(const FString &String)
static EAntiAliasing ConvertStringToAntiAliasingMethod(const FString &String)
EShadowCacheInvalidationBehavior FoliageShadowCacheInvalidationBehaviour