コード例 #1
0
ファイル: BodySetup.cpp プロジェクト: didixp/Ark-Dev-Kit
void GetContactOffsetParams(float& ContactOffsetFactor, float& MaxContactOffset)
{
	// Get contact offset params
	ContactOffsetFactor = CVarContactOffsetFactor.GetValueOnGameThread();
	MaxContactOffset = CVarMaxContactOffset.GetValueOnGameThread();
}
コード例 #2
0
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;
}
コード例 #3
0
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."));
	}
}
コード例 #4
0
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());
		}
	}
}
コード例 #5
0
//////// 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
}
コード例 #6
0
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;
		}
	}
}
コード例 #7
0
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 );
}
コード例 #8
0
ファイル: SceneView.cpp プロジェクト: kidaa/UnrealEngineVR
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);
		}
	}
}
コード例 #9
0
ファイル: SceneView.cpp プロジェクト: kidaa/UnrealEngineVR
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);
		}
	}
}
コード例 #10
0
ファイル: SystemSettings.cpp プロジェクト: stoneStyle/Unreal4
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;
		}
	}
}