void GetContactOffsetParams(float& ContactOffsetFactor, float& MaxContactOffset) { // Get contact offset params ContactOffsetFactor = CVarContactOffsetFactor.GetValueOnGameThread(); MaxContactOffset = CVarMaxContactOffset.GetValueOnGameThread(); }
void UDemoNetDriver::TickDemoRecord( float DeltaSeconds ) { if ( ClientConnections.Num() == 0 ) { return; } if ( FileAr == NULL ) { return; } DemoDeltaTime += DeltaSeconds; const double CurrentSeconds = FPlatformTime::Seconds(); const double RECORD_HZ = CVarDemoRecordHz.GetValueOnGameThread(); const double RECORD_DELAY = 1.0 / RECORD_HZ; if ( CurrentSeconds - LastRecordTime < RECORD_DELAY ) { return; // Not enough real-time has passed to record another frame } LastRecordTime = CurrentSeconds; // Save out a frame DemoFrameNum++; ReplicationFrame++; // Save elapsed game time *FileAr << DemoDeltaTime; #if DEMO_CHECKSUMS == 1 uint32 DeltaTimeChecksum = FCrc::MemCrc32( &DemoDeltaTime, sizeof( DemoDeltaTime ), 0 ); *FileAr << DeltaTimeChecksum; #endif DemoDeltaTime = 0; // Make sure we don't have anything in the buffer for this new frame check( ClientConnections[0]->SendBuffer.GetNumBits() == 0 ); bIsRecordingDemoFrame = true; // Dump any queued packets UDemoNetConnection * ClientDemoConnection = CastChecked< UDemoNetConnection >( ClientConnections[0] ); for ( int32 i = 0; i < ClientDemoConnection->QueuedDemoPackets.Num(); i++ ) { ClientDemoConnection->LowLevelSend( (char*)&ClientDemoConnection->QueuedDemoPackets[i].Data[0], ClientDemoConnection->QueuedDemoPackets[i].Data.Num() ); } ClientDemoConnection->QueuedDemoPackets.Empty(); const bool IsNetClient = ( GetWorld()->GetNetDriver() != NULL && GetWorld()->GetNetDriver()->GetNetMode() == NM_Client ); DemoReplicateActor( World->GetWorldSettings(), ClientConnections[0], IsNetClient ); for ( int32 i = 0; i < World->NetworkActors.Num(); i++ ) { AActor* Actor = World->NetworkActors[i]; Actor->PreReplication( *FindOrCreateRepChangedPropertyTracker( Actor ).Get() ); DemoReplicateActor( Actor, ClientConnections[0], IsNetClient ); } // Make sure nothing is left over ClientConnections[0]->FlushNet(); check( ClientConnections[0]->SendBuffer.GetNumBits() == 0 ); bIsRecordingDemoFrame = false; // Write a count of 0 to signal the end of the frame int32 EndCount = 0; *FileAr << EndCount; }
void FD3D12DynamicRHIModule::FindAdapter() { // Once we chosen one we don't need to do it again. check(ChosenAdapter.IsValid() == 0); // Try to create the DXGIFactory. This will fail if we're not running Vista. TRefCountPtr<IDXGIFactory4> DXGIFactory; SafeCreateDXGIFactory(DXGIFactory.GetInitReference()); if (!DXGIFactory) { return; } bool bAllowPerfHUD = true; #if UE_BUILD_SHIPPING || UE_BUILD_TEST bAllowPerfHUD = false; #endif int32 CVarValue = CVarGraphicsAdapter.GetValueOnGameThread(); const bool bFavorNonIntegrated = CVarValue == -1; TRefCountPtr<IDXGIAdapter> TempAdapter; D3D_FEATURE_LEVEL MaxAllowedFeatureLevel = GetAllowedD3DFeatureLevel(); FD3D12Adapter FirstWithoutIntegratedAdapter; FD3D12Adapter FirstAdapter; bool bIsAnyAMD = false; bool bIsAnyIntel = false; bool bIsAnyNVIDIA = false; // Enumerate the DXGIFactory's adapters. for (uint32 AdapterIndex = 0; DXGIFactory->EnumAdapters(AdapterIndex, TempAdapter.GetInitReference()) != DXGI_ERROR_NOT_FOUND; ++AdapterIndex) { // Check that if adapter supports D3D11. if (TempAdapter) { D3D_FEATURE_LEVEL ActualFeatureLevel = (D3D_FEATURE_LEVEL)0; if (SafeTestD3D12CreateDevice(TempAdapter, MaxAllowedFeatureLevel, &ActualFeatureLevel)) { // Log some information about the available D3D12 adapters. DXGI_ADAPTER_DESC AdapterDesc; VERIFYD3D11RESULT(TempAdapter->GetDesc(&AdapterDesc)); uint32 OutputCount = CountAdapterOutputs(TempAdapter); UE_LOG(LogD3D12RHI, Log, TEXT("Found D3D12 adapter %u: %s (Feature Level %s)"), AdapterIndex, AdapterDesc.Description, GetFeatureLevelString(ActualFeatureLevel) ); UE_LOG(LogD3D12RHI, Log, TEXT("Adapter has %uMB of dedicated video memory, %uMB of dedicated system memory, and %uMB of shared system memory, %d output[s]"), (uint32)(AdapterDesc.DedicatedVideoMemory / (1024*1024)), (uint32)(AdapterDesc.DedicatedSystemMemory / (1024*1024)), (uint32)(AdapterDesc.SharedSystemMemory / (1024*1024)), OutputCount ); bool bIsAMD = AdapterDesc.VendorId == 0x1002; bool bIsIntel = AdapterDesc.VendorId == 0x8086; bool bIsNVIDIA = AdapterDesc.VendorId == 0x10DE; bool bIsWARP = FParse::Param(FCommandLine::Get(), TEXT("warp")); if (bIsAMD) bIsAnyAMD = true; if (bIsIntel) bIsAnyIntel = true; if (bIsNVIDIA) bIsAnyNVIDIA = true; // Simple heuristic but without profiling it's hard to do better const bool bIsIntegrated = bIsIntel; // PerfHUD is for performance profiling const bool bIsPerfHUD = !FCString::Stricmp(AdapterDesc.Description, TEXT("NVIDIA PerfHUD")); FD3D12Adapter CurrentAdapter(AdapterIndex, ActualFeatureLevel); if (!OutputCount && !bIsWARP) { // Add special check to support WARP, which does not have an output associated with it. // This device has no outputs. Reject it, // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205075%28v=vs.85%29.aspx#WARP_new_for_Win8 continue; } if(bIsPerfHUD && !bAllowPerfHUD) { // we don't allow the PerfHUD adapter continue; } if (CVarValue >= 0 && AdapterIndex != CVarValue) { // the user wants a specific adapter, not this one continue; } if (!bIsIntegrated && !FirstWithoutIntegratedAdapter.IsValid()) { FirstWithoutIntegratedAdapter = CurrentAdapter; } if (!FirstAdapter.IsValid()) { FirstAdapter = CurrentAdapter; } } } } if (bFavorNonIntegrated && (bIsAnyAMD || bIsAnyNVIDIA)) { ChosenAdapter = FirstWithoutIntegratedAdapter; // We assume Intel is integrated graphics (slower than discrete) than NVIDIA or AMD cards and rather take a different one if (!ChosenAdapter.IsValid()) { ChosenAdapter = FirstAdapter; } } else { ChosenAdapter = FirstAdapter; } if (ChosenAdapter.IsValid()) { UE_LOG(LogD3D12RHI, Log, TEXT("Chosen D3D12 Adapter Id = %u"), ChosenAdapter.AdapterIndex); } else { UE_LOG(LogD3D12RHI, Error, TEXT("Failed to choose a D3D12 Adapter.")); } }
void RHIDetectAndWarnOfBadDrivers() { int32 CVarValue = CVarWarnOfBadDrivers.GetValueOnGameThread(); if(!GIsRHIInitialized || !CVarValue || GRHIVendorId == 0) { return; } FGPUDriverInfo DriverInfo; // later we should make the globals use the struct directly DriverInfo.VendorId = GRHIVendorId; DriverInfo.DeviceDescription = GRHIAdapterName; DriverInfo.ProviderName = TEXT("Unknown"); DriverInfo.InternalDriverVersion = GRHIAdapterInternalDriverVersion; DriverInfo.UserDriverVersion = GRHIAdapterUserDriverVersion; DriverInfo.DriverDate = GRHIAdapterDriverDate; #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) // for testing if(CVarValue == 2) { DriverInfo.SetNVIDIA(); DriverInfo.DeviceDescription = TEXT("Test NVIDIA (bad)"); DriverInfo.UserDriverVersion = TEXT("346.43"); DriverInfo.InternalDriverVersion = TEXT("9.18.134.643"); DriverInfo.DriverDate = TEXT("01-01-1900"); } else if(CVarValue == 3) { DriverInfo.SetAMD(); DriverInfo.DeviceDescription = TEXT("Test AMD (bad)"); DriverInfo.UserDriverVersion = TEXT("Test Catalyst Version"); DriverInfo.InternalDriverVersion = TEXT("13.152.1.1000"); DriverInfo.DriverDate = TEXT("09-10-13"); } else if(CVarValue == 4) { DriverInfo.SetAMD(); DriverInfo.DeviceDescription = TEXT("Test AMD (good)"); DriverInfo.UserDriverVersion = TEXT("Test Catalyst Version"); DriverInfo.InternalDriverVersion = TEXT("15.30.1025.1001"); DriverInfo.DriverDate = TEXT("01-01-16"); } else if(CVarValue == 5) { DriverInfo.SetIntel(); DriverInfo.DeviceDescription = TEXT("Test Intel (good)"); DriverInfo.UserDriverVersion = TEXT("Test Intel Version"); DriverInfo.InternalDriverVersion = TEXT("8.15.10.2302"); DriverInfo.DriverDate = TEXT("01-01-15"); } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) FGPUHardware DetectedGPUHardware(DriverInfo); if (DriverInfo.IsValid()) { FBlackListEntry BlackListEntry = DetectedGPUHardware.FindDriverBlacklistEntry(); if (BlackListEntry.IsValid()) { bool bLatestBlacklisted = DetectedGPUHardware.IsLatestBlacklisted(); // Note: we don't localize the vendor's name. FString VendorString = DriverInfo.ProviderName; if (DriverInfo.IsNVIDIA()) { VendorString = TEXT("NVIDIA"); } else if (DriverInfo.IsAMD()) { VendorString = TEXT("AMD"); } else if (DriverInfo.IsIntel()) { VendorString = TEXT("Intel"); } // format message box UI FFormatNamedArguments Args; Args.Add(TEXT("AdapterName"), FText::FromString(DriverInfo.DeviceDescription)); Args.Add(TEXT("Vendor"), FText::FromString(VendorString)); Args.Add(TEXT("RecommendedVer"), FText::FromString(DetectedGPUHardware.GetSuggestedDriverVersion())); Args.Add(TEXT("InstalledVer"), FText::FromString(DriverInfo.UserDriverVersion)); // this message can be suppressed with r.WarnOfBadDrivers=0 FText LocalizedMsg; if (bLatestBlacklisted) { LocalizedMsg = FText::Format(NSLOCTEXT("MessageDialog", "LatestVideoCardDriverIssueReport","The latest version of the {Vendor} graphics driver has known issues.\n\nPlease install the last known good driver version.\n\n{AdapterName}\n{RecommendedVer} is the last known good\n{InstalledVer} is installed"),Args); } else { LocalizedMsg = FText::Format(NSLOCTEXT("MessageDialog", "VideoCardDriverIssueReport","Your {Vendor} graphics driver has known issues.\n\nPlease update to the latest driver version.\n\n{AdapterName}\n{RecommendedVer} is recommended\n{InstalledVer} is installed"),Args); } FPlatformMisc::MessageBoxExt(EAppMsgType::Ok, *LocalizedMsg.ToString(), *NSLOCTEXT("MessageDialog", "TitleVideoCardDriverIssue", "WARNING: Known issues with graphics driver").ToString()); } } }
//////// GAME-LEVEL RIGID BODY PHYSICS STUFF /////// void InitGamePhys() { #if WITH_BOX2D FPhysicsIntegration2D::InitializePhysics(); #endif #if WITH_PHYSX // Do nothing if SDK already exists if(GPhysXFoundation != NULL) { return; } // Make sure LoadPhysXModules(); // Create Foundation GPhysXAllocator = new FPhysXAllocator(); FPhysXErrorCallback* ErrorCallback = new FPhysXErrorCallback(); GPhysXFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, *GPhysXAllocator, *ErrorCallback); check(GPhysXFoundation); #if PHYSX_MEMORY_STATS // Want names of PhysX allocations GPhysXFoundation->setReportAllocationNames(true); #endif // Create profile manager GPhysXVisualDebugger = PxCreatePvd(*GPhysXFoundation); check(GPhysXVisualDebugger); // Create Physics PxTolerancesScale PScale; PScale.length = CVarToleranceScaleLength.GetValueOnGameThread(); PScale.speed = CVarToleranceScaleSpeed.GetValueOnGameThread(); GPhysXSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *GPhysXFoundation, PScale, false, GPhysXVisualDebugger); check(GPhysXSDK); FPhysxSharedData::Initialize(); GPhysCommandHandler = new FPhysCommandHandler(); GPreGarbageCollectDelegateHandle = FCoreUObjectDelegates::PreGarbageCollect.AddRaw(GPhysCommandHandler, &FPhysCommandHandler::Flush); // Init Extensions PxInitExtensions(*GPhysXSDK, GPhysXVisualDebugger); #if WITH_VEHICLE PxInitVehicleSDK(*GPhysXSDK); #endif if (CVarUseUnifiedHeightfield.GetValueOnGameThread()) { //Turn on PhysX 3.3 unified height field collision detection. //This approach shares the collision detection code between meshes and height fields such that height fields behave identically to the equivalent terrain created as a mesh. //This approach facilitates mixing the use of height fields and meshes in the application with no tangible difference in collision behavior between the two approaches except that //heightfield thickness is not supported for unified heightfields. PxRegisterUnifiedHeightFields(*GPhysXSDK); } else { PxRegisterHeightFields(*GPhysXSDK); } if( FParse::Param( FCommandLine::Get(), TEXT( "PVD" ) ) ) { PvdConnect(TEXT("localhost"), true); } #if WITH_PHYSICS_COOKING || WITH_RUNTIME_PHYSICS_COOKING // Create Cooking PxCookingParams PCookingParams(PScale); PCookingParams.meshWeldTolerance = 0.1f; // Weld to 1mm precision PCookingParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES); // Force any cooking in PhysX or APEX to use older incremental hull method // This is because the new 'quick hull' method can generate degenerate geometry in some cases (very thin meshes etc.) //PCookingParams.convexMeshCookingType = PxConvexMeshCookingType::eINFLATION_INCREMENTAL_HULL; PCookingParams.targetPlatform = PxPlatform::ePC; //PCookingParams.meshCookingHint = PxMeshCookingHint::eCOOKING_PERFORMANCE; //PCookingParams.meshSizePerformanceTradeOff = 0.0f; GPhysXCooking = PxCreateCooking(PX_PHYSICS_VERSION, *GPhysXFoundation, PCookingParams); check(GPhysXCooking); #endif #if WITH_APEX // Build the descriptor for the APEX SDK apex::ApexSDKDesc ApexDesc; ApexDesc.foundation = GPhysXFoundation; // Pointer to the PxFoundation ApexDesc.physXSDK = GPhysXSDK; // Pointer to the PhysXSDK ApexDesc.cooking = GPhysXCooking; // Pointer to the cooking library ApexDesc.renderResourceManager = &GApexNullRenderResourceManager; // We will not be using the APEX rendering API, so just use a dummy render resource manager ApexDesc.resourceCallback = &GApexResourceCallback; // The resource callback is how APEX asks the application to find assets when it needs them #if PLATFORM_MAC FString DylibFolder = FPaths::EngineDir() / TEXT("Binaries/ThirdParty/PhysX/"); ANSICHAR* DLLLoadPath = (ANSICHAR*)FMemory::Malloc(DylibFolder.Len() + 1); FCStringAnsi::Strcpy(DLLLoadPath, DylibFolder.Len() + 1, TCHAR_TO_UTF8(*DylibFolder)); ApexDesc.dllLoadPath = DLLLoadPath; #endif // Create the APEX SDK apex::ApexCreateError ErrorCode; GApexSDK = apex::CreateApexSDK(ApexDesc, &ErrorCode); check(ErrorCode == APEX_CE_NO_ERROR); check(GApexSDK); #if PLATFORM_MAC FMemory::Free(DLLLoadPath); #endif #if UE_BUILD_SHIPPING GApexSDK->setEnableApexStats(false); #endif #if APEX_STATICALLY_LINKED // We need to instantiate the module if we have statically linked them // Otherwise all createModule functions will fail instantiateModuleDestructible(); #if WITH_APEX_CLOTHING instantiateModuleClothing(); #endif #if WITH_APEX_LEGACY instantiateModuleLegacy(); #endif #endif // 1 legacy module for all in APEX 1.3 // Load the only 1 legacy module #if WITH_APEX_LEGACY GApexModuleLegacy = GApexSDK->createModule("Legacy"); check(GApexModuleLegacy); #endif // WITH_APEX_LEGACY // Load APEX Destruction module GApexModuleDestructible = static_cast<apex::ModuleDestructible*>(GApexSDK->createModule("Destructible")); check(GApexModuleDestructible); // Set Destructible module parameters NvParameterized::Interface* ModuleParams = GApexModuleDestructible->getDefaultModuleDesc(); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleDestructible->init(*ModuleParams); // Set chunk report for fracture effect callbacks GApexModuleDestructible->setChunkReport(&GApexChunkReport); GApexModuleDestructible->setMaxDynamicChunkIslandCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkIslandCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setMaxChunkCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setSortByBenefit(CVarAPEXSortDynamicChunksByBenefit.GetValueOnGameThread() != 0); GApexModuleDestructible->scheduleChunkStateEventCallback(apex::DestructibleCallbackSchedule::FetchResults); // APEX 1.3 to preserve 1.2 behavior GApexModuleDestructible->setUseLegacyDamageRadiusSpread(true); GApexModuleDestructible->setUseLegacyChunkBoundsTesting(true); #if WITH_APEX_CLOTHING // Load APEX Clothing module GApexModuleClothing = static_cast<apex::ModuleClothing*>(GApexSDK->createModule("Clothing")); check(GApexModuleClothing); // Set Clothing module parameters ModuleParams = GApexModuleClothing->getDefaultModuleDesc(); // Can be tuned for switching between more memory and more spikes. NvParameterized::setParamU32(*ModuleParams, "maxUnusedPhysXResources", 5); // If true, let fetch results tasks run longer than the fetchResults call. // Setting to true could not ensure same finish timing with Physx simulation phase NvParameterized::setParamBool(*ModuleParams, "asyncFetchResults", false); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleClothing->init(*ModuleParams); #endif //WITH_APEX_CLOTHING #endif // #if WITH_APEX #endif // WITH_PHYSX }
void FSystemSettings::ApplyOverrides() { bool bUseMaxQualityMode = CVarUseMaxQualityMode.GetValueOnGameThread() != 0; if (FParse::Param(FCommandLine::Get(),TEXT("MAXQUALITYMODE"))) { bUseMaxQualityMode = true; } if (FParse::Param(FCommandLine::Get(),TEXT("MSAA"))) { check(0); // todo: set console variable to activate MSAA } if (!FPlatformProperties::SupportsWindowedMode()) { bUseMaxQualityMode = false; } else { // Dump(TEXT("Startup System Settings:")); } if (bUseMaxQualityMode) { // Modify various system settings to get the best quality regardless of performance impact { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.MinResolution")); CVar->Set(16); } // Disable shadow fading out over distance { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.FadeResolution")); CVar->Set(1); } // Increase minimum preshadow resolution { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.MinPreShadowResolution")); CVar->Set(16); } // Disable preshadow fading out over distance { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.PreShadowFadeResolution")); CVar->Set(1); } // Increase shadow texel density { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.TexelsPerPixel")); CVar->Set(4.0f); } // Don't downsample preshadows { auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.PreShadowResolutionFactor")); CVar->Set(1.0f); } for (int32 GroupIndex = 0; GroupIndex < TEXTUREGROUP_MAX; GroupIndex++) { FTextureLODSettings::FTextureLODGroup& CurrentGroup = TextureLODSettings.GetTextureLODGroup(GroupIndex); // Use the best quality texture filtering CurrentGroup.Filter = SF_AnisotropicLinear; // Raise texture max sizes to 4096 CurrentGroup.MinLODMipCount = 12; CurrentGroup.MaxLODMipCount = 12; CurrentGroup.LODBias = -1000; } } }
void FGridWidget::DrawNewGrid(const FSceneView* View, FPrimitiveDrawInterface* PDI) { if(LevelGridMaterial->IsCompilingOrHadCompileError() || LevelGridMaterial2->IsCompilingOrHadCompileError()) { // The material would appear to be black (because we don't use a MaterialDomain but a UsageFlag - we should change that). // Here we rather want to hide it. return; } bool bUseTextureSolution = CVarEditorNewLevelGrid.GetValueOnGameThread() > 1; UMaterialInstanceDynamic *MaterialInst = bUseTextureSolution ? LevelGridMaterialInst2 : LevelGridMaterialInst; if(!MaterialInst) { return; } bool bMSAA = IsEditorCompositingMSAAEnabled(); bool bIsPerspective = ( View->ViewMatrices.ProjMatrix.M[3][3] < 1.0f ); // 0: off, in unreal units float SnapGridSize = 0.0f; if(GetDefault<ULevelEditorViewportSettings>()->GridEnabled) { SnapGridSize = GEditor->GetGridSize(); } float SnapAlphaMultiplier = 1.0f; if(SnapGridSize <= 0.0f) { // to hide the snap in the texture based solution SnapAlphaMultiplier = 0; } // to get a light grid in a black level but use a high opacity value to be able to see it in a bright level const float Darken = 0.11f; if(bIsPerspective) { MaterialInst->SetVectorParameterValue("GridColor", FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor3DGridFade.GetValueOnGameThread())); MaterialInst->SetVectorParameterValue("SnapColor", FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor3DSnapFade.GetValueOnGameThread())); } else { MaterialInst->SetVectorParameterValue("GridColor", FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor2DGridFade.GetValueOnGameThread())); MaterialInst->SetVectorParameterValue("SnapColor", FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor2DSnapFade.GetValueOnGameThread())); } // true:1m, false:1dm ios smallest grid size bool bLarger1mGrid = true; const int Exponent = 10; // 2 is the default so we need to set it MaterialInst->SetScalarParameterValue("Exponent", (float)Exponent); // without MSAA we need the grid to be more see through so lines behind it can be recognized MaterialInst->SetScalarParameterValue("AlphaBias", bMSAA ? 0.0f : 0.05f); // grid for size float GridSplit = 0.5f; // red dots to visualize the snap float SnapSplit = 0.075f; float WorldToUVScale = 0.001f; if(bLarger1mGrid) { WorldToUVScale *= 0.1f; GridSplit *= 0.1f; } // in 2D all grid lines are same size in world space (they are at different scale so we need to adjust here) FLinearColor GridSplitTriple(GridSplit * 0.01f, GridSplit * 0.1f, GridSplit); if(bIsPerspective) { // largest grid lines GridSplitTriple.R *= 8.0f; // medium grid lines GridSplitTriple.G *= 3.0f; // fine grid lines GridSplitTriple.B *= 1.0f; } if(!bIsPerspective) { // screenspace size looks better in 2d float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0] * View->ViewRect.Width(); float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1] * View->ViewRect.Height(); float Scale = FMath::Min(ScaleX, ScaleY); float GridScale = CVarEditor2DSnapScale.GetValueOnGameThread(); float GridMin = CVarEditor2DSnapMin.GetValueOnGameThread(); // we need to account for a larger grids setting SnapSplit = 1.25f * FMath::Min(GridScale / SnapGridSize / Scale, GridMin); // hack test GridSplitTriple.R = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.01f, GridMin); GridSplitTriple.G = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.1f, GridMin); GridSplitTriple.B = 0.25f * FMath::Min(GridScale / 100 / Scale, GridMin); } // if snap is not enabled and we want to hide it in this view port if(SnapGridSize <= 0.0f || !View->Family->EngineShowFlags.Snap) { // 0.0f is off SnapSplit = 0.0f; } float SnapTile = (1.0f / WorldToUVScale) / FMath::Max(1.0f, SnapGridSize); MaterialInst->SetVectorParameterValue("GridSplit", GridSplitTriple); MaterialInst->SetScalarParameterValue("SnapSplit", SnapSplit); MaterialInst->SetScalarParameterValue("SnapTile", SnapTile); FMatrix ObjectToWorld = FMatrix::Identity; FVector CameraPos = View->ViewMatrices.ViewOrigin; FVector2D UVCameraPos = FVector2D(CameraPos.X, CameraPos.Y); ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, 0)); FLinearColor UAxisColor = FLinearColor::Green; FLinearColor VAxisColor = FLinearColor::Red; if(!bIsPerspective) { float FarZ = 100000.0f; if(View->ViewMatrices.ViewMatrix.M[1][1] == -1.f ) // Top { ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, -FarZ)); } if(View->ViewMatrices.ViewMatrix.M[1][2] == -1.f ) // Front { UVCameraPos = FVector2D(CameraPos.Z, CameraPos.X); ObjectToWorld.SetAxis(0, FVector(0,0,1)); ObjectToWorld.SetAxis(1, FVector(1,0,0)); ObjectToWorld.SetAxis(2, FVector(0,1,0)); ObjectToWorld.SetOrigin(FVector(CameraPos.X, -FarZ, CameraPos.Z)); UAxisColor = FLinearColor::Red; VAxisColor = FLinearColor::Blue; } else if(View->ViewMatrices.ViewMatrix.M[1][0] == 1.f ) // Side { UVCameraPos = FVector2D(CameraPos.Y, CameraPos.Z); ObjectToWorld.SetAxis(0, FVector(0,1,0)); ObjectToWorld.SetAxis(1, FVector(0,0,1)); ObjectToWorld.SetAxis(2, FVector(1,0,0)); ObjectToWorld.SetOrigin(FVector(FarZ, CameraPos.Y, CameraPos.Z)); UAxisColor = FLinearColor::Blue; VAxisColor = FLinearColor::Green; } } // less prominent axis lines { // desaturate UAxisColor += FLinearColor(0.5f, 0.5f, 0.5f, 0); VAxisColor += FLinearColor(0.5f, 0.5f, 0.5f, 0); // darker UAxisColor *= 0.1f; VAxisColor *= 0.1f; } MaterialInst->SetVectorParameterValue("UAxisColor", UAxisColor); MaterialInst->SetVectorParameterValue("VAxisColor", VAxisColor); // We don't want to affect the mouse interaction. PDI->SetHitProxy(0); // good enough to avoid the AMD artifacts, horizon still appears to be a line float Radii = 100000; if(bIsPerspective) { // the higher we get the larger we make the geometry to give the illusion of an infinite grid while maintains the precision nearby Radii *= FMath::Max( 1.0f, FMath::Abs(CameraPos.Z) / 1000.0f ); } else { float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0]; float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1]; float Scale = FMath::Min(ScaleX, ScaleY); Scale *= View->ViewRect.Width(); // We render a larger grid if we are zoomed out more (good precision at any scale) Radii *= 1.0f / Scale; } FVector2D UVMid = UVCameraPos * WorldToUVScale; float UVRadi = Radii * WorldToUVScale; FVector2D UVMin = UVMid + FVector2D(-UVRadi, -UVRadi); FVector2D UVMax = UVMid + FVector2D(UVRadi, UVRadi); // vertex pos is in -1..1 range DrawPlane10x10(PDI, ObjectToWorld, Radii, UVMin, UVMax, MaterialInst->GetRenderProxy(false), SDPG_World ); }
void FSceneView::StartFinalPostprocessSettings(FVector InViewLocation) { check(IsInGameThread()); // The final settings for the current viewer position (blended together from many volumes). // Setup by the main thread, passed to the render thread and never touched again by the main thread. // Set values before any override happens. FinalPostProcessSettings.SetBaseValues(); // project settings might want to have different defaults { if(!CVarDefaultBloom.GetValueOnGameThread()) { FinalPostProcessSettings.BloomIntensity = 0; } if (!CVarDefaultAmbientOcclusion.GetValueOnGameThread()) { FinalPostProcessSettings.AmbientOcclusionIntensity = 0; } if (!CVarDefaultAutoExposure.GetValueOnGameThread()) { FinalPostProcessSettings.AutoExposureMinBrightness = 1; FinalPostProcessSettings.AutoExposureMaxBrightness = 1; } if (!CVarDefaultMotionBlur.GetValueOnGameThread()) { FinalPostProcessSettings.MotionBlurAmount = 0; } if (!CVarDefaultLensFlare.GetValueOnGameThread()) { FinalPostProcessSettings.LensFlareIntensity = 0; } { int32 Value = CVarDefaultAntiAliasing.GetValueOnGameThread(); if (Value >= 0 && Value < AAM_MAX) { FinalPostProcessSettings.AntiAliasingMethod = (EAntiAliasingMethod)Value; } } { int32 Value = CVarDefaultAmbientOcclusionStaticFraction.GetValueOnGameThread(); if(!Value) { FinalPostProcessSettings.AmbientOcclusionStaticFraction = 0.0f; } } } if(State) { State->OnStartPostProcessing(*this); } UWorld* World = Family->Scene->GetWorld(); // Some views have no world (e.g. material preview) if (World) { for (auto VolumeIt = World->PostProcessVolumes.CreateIterator(); VolumeIt; ++VolumeIt) { DoPostProcessVolume(*VolumeIt, InViewLocation, this); } } }
void FSceneView::EndFinalPostprocessSettings(const FSceneViewInitOptions& ViewInitOptions) { { static const auto CVarMobileMSAA = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); if(CVarMobileMSAA ? CVarMobileMSAA->GetValueOnGameThread() > 1 : false) { // Turn off various features which won't work with mobile MSAA. FinalPostProcessSettings.DepthOfFieldScale = 0.0f; FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.BloomQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.BloomIntensity = 0.0f; } } if(!Family->EngineShowFlags.Bloom) { FinalPostProcessSettings.BloomIntensity = 0.0f; } if(!Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.LPVIntensity = 0.0f; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.DepthOfFieldQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.DepthOfFieldScale = 0.0f; } } if(!Family->EngineShowFlags.DepthOfField) { FinalPostProcessSettings.DepthOfFieldScale = 0; } if(!Family->EngineShowFlags.Vignette) { FinalPostProcessSettings.VignetteIntensity = 0; FinalPostProcessSettings.VignetteColor = FLinearColor(0.0f, 0.0f, 0.0f); } if(!Family->EngineShowFlags.Grain) { FinalPostProcessSettings.GrainIntensity = 0; FinalPostProcessSettings.GrainJitter = 0; } if(!Family->EngineShowFlags.CameraImperfections) { FinalPostProcessSettings.BloomDirtMaskIntensity = 0; } if(!Family->EngineShowFlags.AmbientCubemap) { FinalPostProcessSettings.ContributingCubemaps.Empty(); } if(!Family->EngineShowFlags.LensFlares) { FinalPostProcessSettings.LensFlareIntensity = 0; } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarExposureOffset.GetValueOnGameThread(); FinalPostProcessSettings.AutoExposureBias += Value; } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.ScreenPercentage = Value; } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarSSRMaxRoughness.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.ScreenSpaceReflectionMaxRoughness = Value; } } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionStaticFraction")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.AmbientOcclusionStaticFraction = Value; } } if(!Family->EngineShowFlags.ScreenPercentage || bIsSceneCapture || bIsReflectionCapture) { FinalPostProcessSettings.ScreenPercentage = 100; } if(!Family->EngineShowFlags.AmbientOcclusion) { FinalPostProcessSettings.AmbientOcclusionIntensity = 0; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionRadiusScale")); float Scale = FMath::Clamp(CVar->GetValueOnGameThread(), 0.1f, 5.0f); FinalPostProcessSettings.AmbientOcclusionRadius *= Scale; } { float Scale = FMath::Clamp(CVarSSAOFadeRadiusScale.GetValueOnGameThread(), 0.01f, 50.0f); FinalPostProcessSettings.AmbientOcclusionDistance *= Scale; } { float Value = FMath::Clamp(CVarMotionBlurScale.GetValueOnGameThread(), 0.0f, 50.0f); FinalPostProcessSettings.MotionBlurAmount *= Value; } { float Value = CVarMotionBlurMax.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.MotionBlurMax = FMath::Min(FinalPostProcessSettings.MotionBlurMax, Value); } } { float Value = CVarSceneColorFringeMax.GetValueOnGameThread(); if (Value >= 0.0f) { FinalPostProcessSettings.SceneFringeIntensity = FMath::Min(FinalPostProcessSettings.SceneFringeIntensity, Value); } } if (!Family->EngineShowFlags.Lighting || !Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.IndirectLightingColor = FLinearColor(0,0,0,0); FinalPostProcessSettings.IndirectLightingIntensity = 0.0f; } // Anti-Aliasing { const auto FeatureLevel = GetFeatureLevel(); static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PostProcessAAQuality")); static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR")); static auto* MobileMSAACvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); static uint32 MSAAValue = GShaderPlatformForFeatureLevel[FeatureLevel] == SP_OPENGL_ES2_IOS ? 1 : MobileMSAACvar->GetValueOnGameThread(); int32 Quality = FMath::Clamp(CVar->GetValueOnGameThread(), 0, 6); if( !Family->EngineShowFlags.PostProcessing || !Family->EngineShowFlags.AntiAliasing || Quality <= 0 // Disable antialiasing in GammaLDR mode to avoid jittering. || (FeatureLevel == ERHIFeatureLevel::ES2 && MobileHDRCvar->GetValueOnGameThread() == 0) || (FeatureLevel <= ERHIFeatureLevel::ES3_1 && (MSAAValue > 1))) { FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } if( FinalPostProcessSettings.AntiAliasingMethod == AAM_TemporalAA) { if( !Family->EngineShowFlags.TemporalAA || !Family->bRealtimeUpdate || Quality < 3 ) { FinalPostProcessSettings.AntiAliasingMethod = AAM_FXAA; } } } if (AllowDebugViewmodes()) { ConfigureBufferVisualizationSettings(); } #if WITH_EDITOR FHighResScreenshotConfig& Config = GetHighResScreenshotConfig(); // Pass highres screenshot materials through post process settings FinalPostProcessSettings.HighResScreenshotMaterial = Config.HighResScreenshotMaterial; FinalPostProcessSettings.HighResScreenshotMaskMaterial = Config.HighResScreenshotMaskMaterial; FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = NULL; // If the highres screenshot UI is open and we're not taking a highres screenshot this frame if (Config.bDisplayCaptureRegion && !GIsHighResScreenshot) { // Only enable the capture region effect if the capture region is different from the view rectangle... if ((Config.UnscaledCaptureRegion != ViewRect) && (Config.UnscaledCaptureRegion.Area() > 0) && (State != NULL)) { // ...and if this is the viewport associated with the highres screenshot UI auto ConfigViewport = Config.TargetViewport.Pin(); if (ConfigViewport.IsValid() && Family && Family->RenderTarget == ConfigViewport->GetViewport()) { static const FName ParamName = "RegionRect"; FLinearColor NormalizedCaptureRegion; // Normalize capture region into view rectangle NormalizedCaptureRegion.R = (float)Config.UnscaledCaptureRegion.Min.X / (float)ViewRect.Width(); NormalizedCaptureRegion.G = (float)Config.UnscaledCaptureRegion.Min.Y / (float)ViewRect.Height(); NormalizedCaptureRegion.B = (float)Config.UnscaledCaptureRegion.Max.X / (float)ViewRect.Width(); NormalizedCaptureRegion.A = (float)Config.UnscaledCaptureRegion.Max.Y / (float)ViewRect.Height(); // Get a MID for drawing this frame and push the capture region into the shader parameter FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = State->GetReusableMID(Config.HighResScreenshotCaptureRegionMaterial); FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial->SetVectorParameterValue(ParamName, NormalizedCaptureRegion); } } } #endif // WITH_EDITOR // Upscaling or Super sampling { float LocalScreenPercentage = FinalPostProcessSettings.ScreenPercentage; float Fraction = 1.0f; // apply ScreenPercentage if (LocalScreenPercentage != 100.f) { Fraction = FMath::Clamp(LocalScreenPercentage / 100.0f, 0.1f, 4.0f); } // Window full screen mode with upscaling bool bFullscreen = false; if (GEngine && GEngine->GameViewport && GEngine->GameViewport->GetWindow().IsValid()) { bFullscreen = GEngine->GameViewport->GetWindow()->GetWindowMode() != EWindowMode::Windowed; } check(Family->RenderTarget); if (bFullscreen) { // CVar mode 2 is fullscreen with upscale if(GSystemResolution.WindowMode == EWindowMode::WindowedFullscreen) { // FIntPoint WindowSize = Viewport->GetSizeXY(); FIntPoint WindowSize = Family->RenderTarget->GetSizeXY(); // allow only upscaling float FractionX = FMath::Clamp((float)GSystemResolution.ResX / WindowSize.X, 0.1f, 4.0f); float FractionY = FMath::Clamp((float)GSystemResolution.ResY / WindowSize.Y, 0.1f, 4.0f); // maintain a pixel aspect ratio of 1:1 for easier internal computations Fraction *= FMath::Max(FractionX, FractionY); } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if(CVarScreenPercentageEditor.GetValueOnAnyThread() == 0) { bool bNotInGame = GEngine && GEngine->GameViewport == 0; if(bNotInGame) { Fraction = 1.0f; } } #endif // Upscale if needed if (Fraction != 1.0f) { // compute the view rectangle with the ScreenPercentage applied const FIntRect ScreenPercentageAffectedViewRect = ViewInitOptions.GetConstrainedViewRect().Scale(Fraction); SetScaledViewRect(ScreenPercentageAffectedViewRect); } } }
void FSystemSettings::ApplyOverrides() { EConsoleVariableFlags SetBy = ECVF_SetByMask; if (FPlatformProperties::SupportsWindowedMode()) { if (CVarUseMaxQualityMode.GetValueOnGameThread() != 0) { SetBy = (EConsoleVariableFlags)(CVarUseMaxQualityMode.AsVariable()->GetFlags() & ECVF_SetByMask); } if (FParse::Param(FCommandLine::Get(),TEXT("MAXQUALITYMODE"))) { SetBy = ECVF_SetByCommandline; } } if (SetBy != ECVF_SetByMask) { // Modify various system settings to get the best quality regardless of performance impact { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.MinResolution")); CVar->Set(16, SetBy); } // Disable shadow fading out over distance { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.FadeResolution")); CVar->Set(1, SetBy); } // Increase minimum preshadow resolution { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.MinPreShadowResolution")); CVar->Set(16, SetBy); } // Disable preshadow fading out over distance { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.PreShadowFadeResolution")); CVar->Set(1, SetBy); } // Increase shadow texel density { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.TexelsPerPixel")); CVar->Set(4.0f, SetBy); } // Don't downsample preshadows { static auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Shadow.PreShadowResolutionFactor")); CVar->Set(1.0f, SetBy); } for (int32 GroupIndex = 0; GroupIndex < TEXTUREGROUP_MAX; GroupIndex++) { FTextureLODSettings::FTextureLODGroup& CurrentGroup = TextureLODSettings.GetTextureLODGroup(GroupIndex); // Use the best quality texture filtering CurrentGroup.Filter = SF_AnisotropicLinear; // Raise texture max sizes to 4096 CurrentGroup.MinLODMipCount = 12; CurrentGroup.MaxLODMipCount = 12; CurrentGroup.LODBias = -1000; } } }