CARLA
 
载入中...
搜索中...
未找到
CarlaSettingsDelegate.cpp
浏览该文件的文档.
1#include "Carla.h"
4
7
8#include "Async.h"
9#include "Components/StaticMeshComponent.h"
10#include "Engine/DirectionalLight.h"
11#include "Engine/Engine.h"
12#include "Engine/LocalPlayer.h"
13#include "Engine/PostProcessVolume.h"
14#include "Engine/StaticMesh.h"
15#include "GameFramework/HUD.h"
16#include "InstancedFoliageActor.h"
17#include "Kismet/GameplayStatics.h"
18#include "Landscape.h"
19#include "Scalability.h"
20
21
22static constexpr float CARLA_SETTINGS_MAX_SCALE_SIZE = 50.0f;
23
24/// quality settings configuration between runs
26
28 : ActorSpawnedDelegate(FOnActorSpawned::FDelegate::CreateUObject(
29 this,
30 &UCarlaSettingsDelegate::OnActorSpawned)) {}
31
36
38{
39 CheckCarlaSettings(InWorld);
40 InWorld->AddOnActorSpawnedHandler(ActorSpawnedDelegate);
41}
42
44{
45 check(CarlaSettings != nullptr);
46 if (InActor != nullptr && IsValid(InActor) && !InActor->IsPendingKill() &&
47 !InActor->IsA<AInstancedFoliageActor>() && // foliage culling is
48 // controlled per instance
49 !InActor->IsA<ALandscape>() && // dont touch landscapes nor roads
50 !InActor->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG) &&
51 !InActor->ActorHasTag(UCarlaSettings::CARLA_SKY_TAG))
52 {
53 TArray<UPrimitiveComponent *> components;
54 InActor->GetComponents(components);
56 {
57 case EQualityLevel::Low: {
58 // apply settings for this actor for the current quality level
59 float dist = CarlaSettings->LowStaticMeshMaxDrawDistance;
60 const float maxscale = InActor->GetActorScale().GetMax();
61 if (maxscale > CARLA_SETTINGS_MAX_SCALE_SIZE)
62 {
63 dist *= 100.0f;
64 }
65 SetActorComponentsDrawDistance(InActor, dist);
66 break;
67 }
68 default: break;
69 }
70 }
71}
72
74{
75 CheckCarlaSettings(nullptr);
76 UWorld *InWorld = CarlaSettings->GetWorld();
77
78 const EQualityLevel QualityLevel = CarlaSettings->GetQualityLevel();
79
80 if (AppliedLowPostResetQualityLevel == QualityLevel)
81 {
82 return;
83 }
84
85 // enable temporal changes of quality (prevent saving last quality settings to file)
86 Scalability::ToggleTemporaryQualityLevels(true);
87
88 switch (QualityLevel)
89 {
91 {
92 // execute tweaks for quality
94 // iterate all directional lights, deactivate shadows
95 SetAllLights(InWorld, CarlaSettings->LowLightFadeDistance, false, true);
96 // Set all the roads the low quality materials
97 SetAllRoads(InWorld, CarlaSettings->LowRoadPieceMeshMaxDrawDistance, CarlaSettings->LowRoadMaterials);
98 // Set all actors with static meshes a max disntace configured in the
99 // global settings for the low quality
100 SetAllActorsDrawDistance(InWorld, CarlaSettings->LowStaticMeshMaxDrawDistance);
101 // Disable all post process volumes
102 SetPostProcessEffectsEnabled(InWorld, false);
103 break;
104 }
105 default:
106 UE_LOG(LogCarla, Warning, TEXT("Unknown quality level, falling back to default."));
108 {
110 SetAllLights(InWorld, 0.0f, true, false);
111 SetAllRoads(InWorld, 0, CarlaSettings->EpicRoadMaterials);
112 SetAllActorsDrawDistance(InWorld, 0);
113 SetPostProcessEffectsEnabled(InWorld, true);
114 break;
115 }
116 }
117 AppliedLowPostResetQualityLevel = QualityLevel;
118}
119
121{
122 CheckCarlaSettings(nullptr);
123 UWorld *InWorld = CarlaSettings->GetWorld();
124 if (!IsValid(InWorld) || InWorld->IsPendingKill())
125 {
126 return;
127 }
128 // enable or disable world and hud rendering
129 APlayerController *playercontroller = UGameplayStatics::GetPlayerController(InWorld, 0);
130 if (playercontroller)
131 {
132 ULocalPlayer *player = playercontroller->GetLocalPlayer();
133 if (player)
134 {
135 player->ViewportClient->bDisableWorldRendering = CarlaSettings->bDisableRendering;
136 }
137 // if we already have a hud class:
138 AHUD *hud = playercontroller->GetHUD();
139 if (hud)
140 {
141 hud->bShowHUD = !CarlaSettings->bDisableRendering;
142 }
143 }
144
145}
146
148{
149 return GEngine->GetWorldFromContextObjectChecked(this);
150}
151
153{
155 {
156 return;
157 }
158 if (world == nullptr || !IsValid(world) || world->IsPendingKill())
159 {
160 world = GetLocalWorld();
161 }
162 check(world != nullptr);
163 auto GameInstance = Cast<UCarlaGameInstance>(world->GetGameInstance());
164 check(GameInstance != nullptr);
165 CarlaSettings = &GameInstance->GetCarlaSettings();
166 check(CarlaSettings != nullptr);
167}
168
170{
171 if (!world)
172 {
173 return;
174 }
175
176 // launch commands to lower quality settings
177 GEngine->Exec(world, TEXT("r.DefaultFeature.MotionBlur 0"));
178 GEngine->Exec(world, TEXT("r.DefaultFeature.Bloom 0"));
179 GEngine->Exec(world, TEXT("r.DefaultFeature.AmbientOcclusion 0"));
180 GEngine->Exec(world, TEXT("r.AmbientOcclusionLevels 0"));
181 GEngine->Exec(world, TEXT("r.DefaultFeature.AmbientOcclusionStaticFraction 0"));
182 GEngine->Exec(world, TEXT("r.RHICmdBypass 0"));
183 GEngine->Exec(world, TEXT("r.DefaultFeature.AntiAliasing 1"));
184 GEngine->Exec(world, TEXT("r.Streaming.PoolSize 2000"));
185 GEngine->Exec(world, TEXT("r.HZBOcclusion 0"));
186 GEngine->Exec(world, TEXT("r.MinScreenRadiusForLights 0.01"));
187 GEngine->Exec(world, TEXT("r.SeparateTranslucency 0"));
188 GEngine->Exec(world, TEXT("r.FinishCurrentFrame 0"));
189 GEngine->Exec(world, TEXT("r.MotionBlurQuality 0"));
190 GEngine->Exec(world, TEXT("r.PostProcessAAQuality 0"));
191 GEngine->Exec(world, TEXT("r.BloomQuality 1"));
192 GEngine->Exec(world, TEXT("r.SSR.Quality 0"));
193 GEngine->Exec(world, TEXT("r.DepthOfFieldQuality 0"));
194 GEngine->Exec(world, TEXT("r.SceneColorFormat 2"));
195 GEngine->Exec(world, TEXT("r.TranslucencyVolumeBlur 0"));
196 GEngine->Exec(world, TEXT("r.TranslucencyLightingVolumeDim 4"));
197 GEngine->Exec(world, TEXT("r.MaxAnisotropy 8"));
198 GEngine->Exec(world, TEXT("r.LensFlareQuality 0"));
199 GEngine->Exec(world, TEXT("r.SceneColorFringeQuality 0"));
200 GEngine->Exec(world, TEXT("r.FastBlurThreshold 0"));
201 GEngine->Exec(world, TEXT("r.SSR.MaxRoughness 0.1"));
202 GEngine->Exec(world, TEXT("r.AllowOcclusionQueries 1"));
203 GEngine->Exec(world, TEXT("r.SSR 0"));
204 // GEngine->Exec(world,TEXT("r.StencilForLODDither 1")); //readonly
205 GEngine->Exec(world, TEXT("r.EarlyZPass 2")); // transparent before opaque
206 GEngine->Exec(world, TEXT("r.EarlyZPassMovable 1"));
207 GEngine->Exec(world, TEXT("Foliage.DitheredLOD 0"));
208 // GEngine->Exec(world,TEXT("r.ForwardShading 0")); //readonly
209 GEngine->Exec(world, TEXT("sg.PostProcessQuality 0"));
210 // GEngine->Exec(world,TEXT("r.ViewDistanceScale 0.1")); //--> too extreme
211 // (far clip too short)
212 GEngine->Exec(world, TEXT("sg.ShadowQuality 0"));
213 GEngine->Exec(world, TEXT("sg.TextureQuality 0"));
214 GEngine->Exec(world, TEXT("sg.EffectsQuality 0"));
215 GEngine->Exec(world, TEXT("sg.FoliageQuality 0"));
216 GEngine->Exec(world, TEXT("foliage.DensityScale 0"));
217 GEngine->Exec(world, TEXT("grass.DensityScale 0"));
218 GEngine->Exec(world, TEXT("r.TranslucentLightingVolume 0"));
219 GEngine->Exec(world, TEXT("r.LightShaftDownSampleFactor 4"));
220 GEngine->Exec(world, TEXT("r.OcclusionQueryLocation 1"));
221 // GEngine->Exec(world,TEXT("r.BasePassOutputsVelocity 0")); //--> readonly
222 // GEngine->Exec(world,TEXT("r.DetailMode 0")); //-->will change to lods 0
223 GEngine->Exec(world, TEXT("r.DefaultFeature.AutoExposure 1"));
224
225}
226
228 UWorld *world,
229 const float max_draw_distance,
230 const TArray<FStaticMaterial> &road_pieces_materials) const
231{
232 if (!world || !IsValid(world) || world->IsPendingKill())
233 {
234 return;
235 }
236 AsyncTask(ENamedThreads::GameThread, [=]() {
237 if (!world || !IsValid(world) || world->IsPendingKill())
238 {
239 return;
240 }
241 TArray<AActor *> actors;
242 UGameplayStatics::GetAllActorsWithTag(world, UCarlaSettings::CARLA_ROAD_TAG, actors);
243
244 for (int32 i = 0; i < actors.Num(); i++)
245 {
246 AActor *actor = actors[i];
247 if (!IsValid(actor) || actor->IsPendingKill())
248 {
249 continue;
250 }
251 TArray<UStaticMeshComponent *> components;
252 actor->GetComponents(components);
253 for (int32 j = 0; j < components.Num(); j++)
254 {
255 UStaticMeshComponent *staticmeshcomponent = Cast<UStaticMeshComponent>(components[j]);
256 if (staticmeshcomponent)
257 {
258 staticmeshcomponent->bAllowCullDistanceVolume = (max_draw_distance > 0);
259 staticmeshcomponent->bUseAsOccluder = false;
260 staticmeshcomponent->LDMaxDrawDistance = max_draw_distance;
261 staticmeshcomponent->CastShadow = (max_draw_distance == 0);
262 if (road_pieces_materials.Num() > 0)
263 {
264 TArray<FName> meshslotsnames = staticmeshcomponent->GetMaterialSlotNames();
265 for (int32 k = 0; k < meshslotsnames.Num(); k++)
266 {
267 const FName &slotname = meshslotsnames[k];
268 road_pieces_materials.ContainsByPredicate(
269 [staticmeshcomponent, slotname](const FStaticMaterial &material)
270 {
271 if (material.MaterialSlotName.IsEqual(slotname))
272 {
273 staticmeshcomponent->SetMaterial(
274 staticmeshcomponent->GetMaterialIndex(slotname),
275 material.MaterialInterface);
276 return true;
277 }
278 else
279 {
280 return false;
281 }
282 });
283 }
284 }
285 }
286 }
287 }
288 }); // ,DELAY_TIME_TO_SET_ALL_ROADS, false);
289}
290
292 AActor *actor,
293 const float max_draw_distance) const
294{
295 if (!actor)
296 {
297 return;
298 }
299 TArray<UPrimitiveComponent *> components;
300 actor->GetComponents(components, false);
301 float dist = max_draw_distance;
302 const float maxscale = actor->GetActorScale().GetMax();
303 if (maxscale > CARLA_SETTINGS_MAX_SCALE_SIZE)
304 {
305 dist *= 100.0f;
306 }
307 for (int32 j = 0; j < components.Num(); j++)
308 {
309 UPrimitiveComponent *primitivecomponent = Cast<UPrimitiveComponent>(components[j]);
310 if (IsValid(primitivecomponent))
311 {
312 primitivecomponent->SetCullDistance(dist);
313 primitivecomponent->bAllowCullDistanceVolume = dist > 0;
314 }
315 }
316}
317
318void UCarlaSettingsDelegate::SetAllActorsDrawDistance(UWorld *world, const float max_draw_distance) const
319{
320 /// @TODO: use semantics to grab all actors by type
321 /// (vehicles,ground,people,props) and set different distances configured in
322 /// the global properties
323 if (!world || !IsValid(world) || world->IsPendingKill())
324 {
325 return;
326 }
327 AsyncTask(ENamedThreads::GameThread, [=]() {
328 if (!world || !IsValid(world) || world->IsPendingKill())
329 {
330 return;
331 }
332 TArray<AActor *> actors;
333 // set the lower quality - max draw distance
334 UGameplayStatics::GetAllActorsOfClass(world, AActor::StaticClass(), actors);
335 for (int32 i = 0; i < actors.Num(); i++)
336 {
337 AActor *actor = actors[i];
338 if (!IsValid(actor) || actor->IsPendingKill() ||
339 actor->IsA<AInstancedFoliageActor>() || // foliage culling is controlled
340 // per instance
341 actor->IsA<ALandscape>() || // dont touch landscapes nor roads
342 actor->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG) ||
343 actor->ActorHasTag(UCarlaSettings::CARLA_SKY_TAG))
344 {
345 continue;
346 }
347 SetActorComponentsDrawDistance(actor, max_draw_distance);
348 }
349 });
350}
351
352void UCarlaSettingsDelegate::SetPostProcessEffectsEnabled(UWorld *world, const bool enabled) const
353{
354 TArray<AActor *> actors;
355 UGameplayStatics::GetAllActorsOfClass(world, APostProcessVolume::StaticClass(), actors);
356 for (int32 i = 0; i < actors.Num(); i++)
357 {
358 AActor *actor = actors[i];
359 if (!IsValid(actor) || actor->IsPendingKill())
360 {
361 continue;
362 }
363 APostProcessVolume *postprocessvolume = Cast<APostProcessVolume>(actor);
364 if (postprocessvolume)
365 {
366 postprocessvolume->bEnabled = enabled;
367 }
368 }
369}
370
372{
373 if (!world)
374 {
375 return;
376 }
377
378 GEngine->Exec(world, TEXT("r.AmbientOcclusionLevels -1"));
379 GEngine->Exec(world, TEXT("r.RHICmdBypass 1"));
380 GEngine->Exec(world, TEXT("r.DefaultFeature.AntiAliasing 1"));
381 GEngine->Exec(world, TEXT("r.Streaming.PoolSize 2000"));
382 GEngine->Exec(world, TEXT("r.MinScreenRadiusForLights 0.03"));
383 GEngine->Exec(world, TEXT("r.SeparateTranslucency 1"));
384 GEngine->Exec(world, TEXT("r.PostProcessAAQuality 4"));
385 GEngine->Exec(world, TEXT("r.BloomQuality 5"));
386 GEngine->Exec(world, TEXT("r.SSR.Quality 3"));
387 GEngine->Exec(world, TEXT("r.DepthOfFieldQuality 2"));
388 GEngine->Exec(world, TEXT("r.SceneColorFormat 4"));
389 GEngine->Exec(world, TEXT("r.TranslucencyVolumeBlur 1"));
390 GEngine->Exec(world, TEXT("r.TranslucencyLightingVolumeDim 64"));
391 GEngine->Exec(world, TEXT("r.MaxAnisotropy 8"));
392 GEngine->Exec(world, TEXT("r.LensFlareQuality 2"));
393 GEngine->Exec(world, TEXT("r.SceneColorFringeQuality 1"));
394 GEngine->Exec(world, TEXT("r.FastBlurThreshold 100"));
395 GEngine->Exec(world, TEXT("r.SSR.MaxRoughness -1"));
396 // GEngine->Exec(world,TEXT("r.StencilForLODDither 0")); //readonly
397 GEngine->Exec(world, TEXT("r.EarlyZPass 3"));
398 GEngine->Exec(world, TEXT("r.EarlyZPassMovable 1"));
399 GEngine->Exec(world, TEXT("Foliage.DitheredLOD 1"));
400 GEngine->Exec(world, TEXT("sg.PostProcessQuality 3"));
401 GEngine->Exec(world, TEXT("r.ViewDistanceScale 1")); // --> too extreme (far
402 // clip too short)
403 GEngine->Exec(world, TEXT("sg.ShadowQuality 3"));
404 GEngine->Exec(world, TEXT("sg.TextureQuality 3"));
405 GEngine->Exec(world, TEXT("sg.EffectsQuality 3"));
406 GEngine->Exec(world, TEXT("sg.FoliageQuality 3"));
407 GEngine->Exec(world, TEXT("foliage.DensityScale 1"));
408 GEngine->Exec(world, TEXT("grass.DensityScale 1"));
409 GEngine->Exec(world, TEXT("r.TranslucentLightingVolume 1"));
410 GEngine->Exec(world, TEXT("r.LightShaftDownSampleFactor 2"));
411 // GEngine->Exec(world,TEXT("r.OcclusionQueryLocation 0"));
412 // GEngine->Exec(world,TEXT("r.BasePassOutputsVelocity 0")); //readonly
413 GEngine->Exec(world, TEXT("r.DetailMode 2"));
414}
415
417 UWorld *world,
418 const float max_distance_fade,
419 const bool cast_shadows,
420 const bool hide_non_directional) const
421{
422 if (!world || !IsValid(world) || world->IsPendingKill())
423 {
424 return;
425 }
426 AsyncTask(ENamedThreads::GameThread, [=]() {
427 if (!world || !IsValid(world) || world->IsPendingKill())
428 {
429 return;
430 }
431 TArray<AActor *> actors;
432 UGameplayStatics::GetAllActorsOfClass(world, ALight::StaticClass(), actors);
433 for (int32 i = 0; i < actors.Num(); i++)
434 {
435 if (!IsValid(actors[i]) || actors[i]->IsPendingKill())
436 {
437 continue;
438 }
439 // tweak directional lights
440 ADirectionalLight *directionallight = Cast<ADirectionalLight>(actors[i]);
441 if (directionallight)
442 {
443 directionallight->SetCastShadows(cast_shadows);
444 directionallight->SetLightFunctionFadeDistance(max_distance_fade);
445 continue;
446 }
447 // disable any other type of light
448 actors[i]->SetActorHiddenInGame(hide_non_directional);
449 }
450 });
451
452}
static constexpr float CARLA_SETTINGS_MAX_SCALE_SIZE
EQualityLevel
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
Used to set settings for every actor that is spawned into the world.
void SetAllRoads(UWorld *world, float max_draw_distance, const TArray< FStaticMaterial > &road_pieces_materials) const
void SetPostProcessEffectsEnabled(UWorld *world, bool enabled) const
void ApplyQualityLevelPreRestart()
Before loading a level, apply the current settings.
void LaunchLowQualityCommands(UWorld *world) const
Execute engine commands to apply the low quality level to the world.
void ApplyQualityLevelPostRestart()
After loading a level, apply the current settings.
void Reset()
Reset settings to default.
void LaunchEpicQualityCommands(UWorld *world) const
Execute engine commands to apply the epic quality level to the world.
void CheckCarlaSettings(UWorld *world)
Check that the world, instance and settings are valid and save the CarlaSettings instance.
void SetAllActorsDrawDistance(UWorld *world, float max_draw_distance) const
void RegisterSpawnHandler(UWorld *World)
Create the event trigger handler for all the newly spawned actors to be processed with a custom funct...
FOnActorSpawned::FDelegate ActorSpawnedDelegate
static EQualityLevel AppliedLowPostResetQualityLevel
Currently applied quality level after level is restarted.
void SetAllLights(UWorld *world, float max_distance_fade, bool cast_shadows, bool hide_non_directional) const
void OnActorSpawned(AActor *Actor)
Function to apply to the actor that is being spawned to apply the current settings.
void SetActorComponentsDrawDistance(AActor *actor, float max_draw_distance) const
bool bDisableRendering
Enable or disable the viewport rendering of the world.
EQualityLevel GetQualityLevel() const
static const FName CARLA_SKY_TAG
CARLA_SKY name to tag the sky sphere (BPS) actors in the scenes.
static const FName CARLA_ROAD_TAG
CARLA_ROAD name to tag road mesh actors.
float LowLightFadeDistance
Distance at which the light function should be completely faded to DisabledBrightness.