void SVectorInputBox::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { bool bFoop = bCanBeCrushed && (CVarCrushThem.GetValueOnAnyThread() > 0.0f); if (bFoop) { const float AlottedWidth = AllottedGeometry.Size.X; const float CrushBelow = CVarStartCrushWhenBelow.GetValueOnAnyThread(); const float StopCrushing = CVarStopCrushWhenAbove.GetValueOnAnyThread(); if (bIsBeingCrushed) { bIsBeingCrushed = AlottedWidth < StopCrushing; } else { bIsBeingCrushed = AlottedWidth < CrushBelow; } } else { bIsBeingCrushed = false; } SCompoundWidget::OnArrangeChildren(AllottedGeometry, ArrangedChildren); }
void FSceneRenderer::InitFogConstants() { // console command override float FogDensityOverride = -1.0f; float FogStartDistanceOverride = -1.0f; #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { // console variable overrides FogDensityOverride = CVarFogDensity.GetValueOnAnyThread(); FogStartDistanceOverride = CVarFogStartDistance.GetValueOnAnyThread(); } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) for(int32 ViewIndex = 0;ViewIndex < Views.Num();ViewIndex++) { FViewInfo& View = Views[ViewIndex]; // set fog consts based on height fog components if(ShouldRenderFog(*View.Family)) { if (Scene->ExponentialFogs.Num() > 0) { const FExponentialHeightFogSceneInfo& FogInfo = Scene->ExponentialFogs[0]; const float CosTerminatorAngle = FMath::Clamp(FMath::Cos(FogInfo.LightTerminatorAngle * PI / 180.0f), -1.0f + DELTA, 1.0f - DELTA); const float CollapsedFogParameterPower = FMath::Clamp( -FogInfo.FogHeightFalloff * (View.ViewMatrices.ViewOrigin.Z - FogInfo.FogHeight), -126.f + 1.f, // min and max exponent values for IEEE floating points (http://en.wikipedia.org/wiki/IEEE_floating_point) +127.f - 1.f ); const float CollapsedFogParameter = FogInfo.FogDensity * FMath::Pow(2.0f, CollapsedFogParameterPower); View.ExponentialFogParameters = FVector4(CollapsedFogParameter, FogInfo.FogHeightFalloff, CosTerminatorAngle, FogInfo.StartDistance); View.ExponentialFogColor = FVector(FogInfo.FogColor.R, FogInfo.FogColor.G, FogInfo.FogColor.B); View.FogMaxOpacity = FogInfo.FogMaxOpacity; View.DirectionalInscatteringExponent = FogInfo.DirectionalInscatteringExponent; View.DirectionalInscatteringStartDistance = FogInfo.DirectionalInscatteringStartDistance; View.bUseDirectionalInscattering = false; View.InscatteringLightDirection = FVector(0); for (TSparseArray<FLightSceneInfoCompact>::TConstIterator It(Scene->Lights); It; ++It) { const FLightSceneInfoCompact& LightInfo = *It; // This will find the first directional light that is set to be used as an atmospheric sun light of sufficient brightness. // If you have more than one directional light with these properties then all subsequent lights will be ignored. if (LightInfo.LightSceneInfo->Proxy->GetLightType() == LightType_Directional && LightInfo.LightSceneInfo->Proxy->IsUsedAsAtmosphereSunLight() && LightInfo.LightSceneInfo->Proxy->GetColor().ComputeLuminance() > KINDA_SMALL_NUMBER && FogInfo.DirectionalInscatteringColor.ComputeLuminance() > KINDA_SMALL_NUMBER) { View.InscatteringLightDirection = -LightInfo.LightSceneInfo->Proxy->GetDirection(); View.bUseDirectionalInscattering = true; View.DirectionalInscatteringColor = FogInfo.DirectionalInscatteringColor * LightInfo.LightSceneInfo->Proxy->GetColor().ComputeLuminance(); break; } } } } } }
FSceneViewFamily::FSceneViewFamily( const ConstructionValues& CVS ) : FamilySizeX(0), FamilySizeY(0), RenderTarget(CVS.RenderTarget), bUseSeparateRenderTarget(false), Scene(CVS.Scene), EngineShowFlags(CVS.EngineShowFlags), CurrentWorldTime(CVS.CurrentWorldTime), DeltaWorldTime(CVS.DeltaWorldTime), CurrentRealTime(CVS.CurrentRealTime), FrameNumber(UINT_MAX), bRealtimeUpdate(CVS.bRealtimeUpdate), bDeferClear(CVS.bDeferClear), bResolveScene(CVS.bResolveScene), GammaCorrection(CVS.GammaCorrection) { // If we do not pass a valid scene pointer then SetWorldTimes must be called to initialized with valid times. ensure(CVS.bTimesSet); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) int32 Value = CVarRenderTimeFrozen.GetValueOnAnyThread(); if(Value) { CurrentWorldTime = 0; CurrentRealTime = 0; } #endif #if !WITH_EDITOR // Console shader compilers don't set instruction count, // Also various console-specific rendering paths haven't been tested with shader complexity check(!EngineShowFlags.ShaderComplexity); check(!EngineShowFlags.StationaryLightOverlap); #else // instead of checking IsGameWorld on rendering thread to see if we allow this flag to be disabled // we force it on in the game thread. if(IsInGameThread()) { if ( Scene && Scene->GetWorld() && Scene->GetWorld()->IsGameWorld() ) { EngineShowFlags.LOD = 1; } } LandscapeLODOverride = -1; bDrawBaseInfo = true; #endif // Not supported in ES2. auto FeatureLevel = GetFeatureLevel(); if (FeatureLevel == ERHIFeatureLevel::ES2 || FeatureLevel == ERHIFeatureLevel::ES3_1) { EngineShowFlags.ScreenPercentage = false; } }
// to avoid having direct access from many places static int GetReflectionEnvironmentCVar() { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) return CVarReflectionEnvironment.GetValueOnAnyThread(); #endif // on, default mode return 1; }
void FAnimNode_AimOffsetLookAt::Evaluate(FPoseContext& Context) { // Evaluate base pose BasePose.Evaluate(Context); if (bIsLODEnabled && FAnimWeight::IsRelevant(Alpha) && (CVarAimOffsetLookAtEnable.GetValueOnAnyThread() == 1)) { UpdateFromLookAtTarget(Context); // Evaluate MeshSpaceRotation additive blendspace FPoseContext MeshSpaceRotationAdditivePoseContext(Context); FAnimNode_BlendSpacePlayer::Evaluate(MeshSpaceRotationAdditivePoseContext); // Accumulate poses together FAnimationRuntime::AccumulateMeshSpaceRotationAdditiveToLocalPose(Context.Pose, MeshSpaceRotationAdditivePoseContext.Pose, Context.Curve, MeshSpaceRotationAdditivePoseContext.Curve, Alpha); // Resulting rotations are not normalized, so normalize here. Context.Pose.NormalizeRotations(); } }
void FVulkanPipelineStateCache::InitAndLoad(const TArray<FString>& CacheFilenames) { TArray<uint8> DeviceCache; bool bLoaded = false; if (GEnablePipelineCacheLoadCvar.GetValueOnAnyThread() == 0) { UE_LOG(LogVulkanRHI, Display, TEXT("Not loading pipeline cache per r.Vulkan.PipelineCacheLoad=0")); } else { bLoaded = Load(CacheFilenames, DeviceCache); } VkPipelineCacheCreateInfo PipelineCacheInfo; FMemory::Memzero(PipelineCacheInfo); PipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; PipelineCacheInfo.initialDataSize = bLoaded ? DeviceCache.Num() : 0; PipelineCacheInfo.pInitialData = bLoaded ? DeviceCache.GetData() : 0; VERIFYVULKANRESULT(VulkanRHI::vkCreatePipelineCache(Device->GetInstanceHandle(), &PipelineCacheInfo, nullptr, &PipelineCache)); }
bool FVelocityRendering::OutputsToGBuffer() { return CVarBasePassOutputsVelocity.GetValueOnAnyThread() == 1; }
void FAnimNode_StateMachine::Update(const FAnimationUpdateContext& Context) { // If we just became relevant and haven't been initialized yet, then reinitialize state machine. if (!bFirstUpdate && (UpdateCounter.Get() != INDEX_NONE) && !UpdateCounter.WasSynchronizedInTheLastFrame(Context.AnimInstanceProxy->GetUpdateCounter()) && (CVarAnimStateMachineRelevancyReset.GetValueOnAnyThread() == 1)) { FAnimationInitializeContext InitializationContext(Context.AnimInstanceProxy); Initialize(InitializationContext); } UpdateCounter.SynchronizeWith(Context.AnimInstanceProxy->GetUpdateCounter()); const FBakedAnimationStateMachine* Machine = GetMachineDescription(); if (Machine != nullptr) { if (Machine->States.Num() == 0) { return; } else if(!Machine->States.IsValidIndex(CurrentState)) { // Attempting to catch a crash where the state machine has been freed. // Reported as a symptom of a crash in UE-24732 for 4.10. This log message should not appear given changes to // re-instancing in 4.11 (see CL 2823202). If it does appear we need to spot integrate CL 2823202 (and supporting // anim re-init changes, probably 2799786 & 2801372). UE_LOG(LogAnimation, Warning, TEXT("FAnimNode_StateMachine::Update - Invalid current state, please report. Attempting to use state %d of %d in state machine %d (ptr 0x%x)"), CurrentState, Machine->States.Num(), StateMachineIndexInClass, Machine); UE_LOG(LogAnimation, Warning, TEXT("\t\tWhen updating AnimInstance: %s"), *Context.AnimInstanceProxy->GetAnimInstanceObject()->GetName()) return; } }
FD3D12DynamicRHI::FD3D12DynamicRHI(IDXGIFactory4* InDXGIFactory, FD3D12Adapter& InAdapter) : DXGIFactory(InDXGIFactory), CommitResourceTableCycles(0), CacheResourceTableCalls(0), CacheResourceTableCycles(0), SetShaderTextureCycles(0), SetShaderTextureCalls(0), SetTextureInTableCalls(0), SceneFrameCounter(0), ResourceTableFrameCounter(INDEX_NONE), bForceSingleQueueGPU(false), NumThreadDynamicHeapAllocators(0), ViewportFrameCounter(0), MainAdapter(InAdapter), MainDevice(nullptr) { FMemory::Memzero(ThreadDynamicHeapAllocatorArray, sizeof(ThreadDynamicHeapAllocatorArray)); // The FD3D12DynamicRHI must be a singleton check(SingleD3DRHI == nullptr); // This should be called once at the start check( IsInGameThread() ); check( !GIsThreadedRendering ); SingleD3DRHI = this; check(MainAdapter.IsValid()); MainDevice = new FD3D12Device(this, DXGIFactory, MainAdapter); FeatureLevel = MainAdapter.MaxSupportedFeatureLevel; GPUProfilingData.Init(MainDevice); #if SUPPORTS_MEMORY_RESIDENCY ResourceResidencyManager.Init(MainDevice); #endif // Allocate a buffer of zeroes. This is used when we need to pass D3D memory // that we don't care about and will overwrite with valid data in the future. ZeroBufferSize = FMath::Max(CVarD3D12ZeroBufferSizeInMB.GetValueOnAnyThread(), 0) * (1 << 20); ZeroBuffer = FMemory::Malloc(ZeroBufferSize); FMemory::Memzero(ZeroBuffer,ZeroBufferSize); GPoolSizeVRAMPercentage = 0; GTexturePoolSize = 0; GConfig->GetInt(TEXT("TextureStreaming"), TEXT("PoolSizeVRAMPercentage"), GPoolSizeVRAMPercentage, GEngineIni); // Initialize the RHI capabilities. check(FeatureLevel == D3D_FEATURE_LEVEL_11_0 || FeatureLevel == D3D_FEATURE_LEVEL_10_0 ); if (FeatureLevel == D3D_FEATURE_LEVEL_10_0) { GSupportsDepthFetchDuringDepthTest = false; } // ES2 feature level emulation in D3D11 if (FParse::Param(FCommandLine::Get(), TEXT("FeatureLevelES2")) && !GIsEditor) { GMaxRHIFeatureLevel = ERHIFeatureLevel::ES2; GMaxRHIShaderPlatform = SP_PCD3D_ES2; } else if ((FParse::Param(FCommandLine::Get(), TEXT("FeatureLevelES31")) || FParse::Param(FCommandLine::Get(), TEXT("FeatureLevelES3_1"))) && !GIsEditor) { GMaxRHIFeatureLevel = ERHIFeatureLevel::ES3_1; GMaxRHIShaderPlatform = SP_PCD3D_ES3_1; } else if (FeatureLevel == D3D_FEATURE_LEVEL_11_0) { GMaxRHIFeatureLevel = ERHIFeatureLevel::SM5; GMaxRHIShaderPlatform = SP_PCD3D_SM5; } else if (FeatureLevel == D3D_FEATURE_LEVEL_10_0) { GMaxRHIFeatureLevel = ERHIFeatureLevel::SM4; GMaxRHIShaderPlatform = SP_PCD3D_SM4; } if (FParse::Param(FCommandLine::Get(), TEXT("ForceSingleQueue"))) { bForceSingleQueueGPU = true; } // Initialize the platform pixel format map. GPixelFormats[ PF_Unknown ].PlatformFormat = DXGI_FORMAT_UNKNOWN; GPixelFormats[ PF_A32B32G32R32F ].PlatformFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; GPixelFormats[ PF_B8G8R8A8 ].PlatformFormat = DXGI_FORMAT_B8G8R8A8_TYPELESS; GPixelFormats[ PF_G8 ].PlatformFormat = DXGI_FORMAT_R8_UNORM; GPixelFormats[ PF_G16 ].PlatformFormat = DXGI_FORMAT_R16_UNORM; GPixelFormats[ PF_DXT1 ].PlatformFormat = DXGI_FORMAT_BC1_TYPELESS; GPixelFormats[ PF_DXT3 ].PlatformFormat = DXGI_FORMAT_BC2_TYPELESS; GPixelFormats[ PF_DXT5 ].PlatformFormat = DXGI_FORMAT_BC3_TYPELESS; GPixelFormats[ PF_BC4 ].PlatformFormat = DXGI_FORMAT_BC4_UNORM; GPixelFormats[ PF_UYVY ].PlatformFormat = DXGI_FORMAT_UNKNOWN; // TODO: Not supported in D3D11 #if DEPTH_32_BIT_CONVERSION GPixelFormats[ PF_DepthStencil ].PlatformFormat = DXGI_FORMAT_R32G8X24_TYPELESS; GPixelFormats[ PF_DepthStencil ].BlockBytes = 5; GPixelFormats[ PF_X24_G8 ].PlatformFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; GPixelFormats[ PF_X24_G8].BlockBytes = 5; #else GPixelFormats[ PF_DepthStencil ].PlatformFormat = DXGI_FORMAT_R24G8_TYPELESS; GPixelFormats[ PF_DepthStencil ].BlockBytes = 4; GPixelFormats[ PF_X24_G8 ].PlatformFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; GPixelFormats[ PF_X24_G8].BlockBytes = 4; #endif GPixelFormats[ PF_ShadowDepth ].PlatformFormat = DXGI_FORMAT_R16_TYPELESS; GPixelFormats[ PF_ShadowDepth ].BlockBytes = 2; GPixelFormats[ PF_R32_FLOAT ].PlatformFormat = DXGI_FORMAT_R32_FLOAT; GPixelFormats[ PF_G16R16 ].PlatformFormat = DXGI_FORMAT_R16G16_UNORM; GPixelFormats[ PF_G16R16F ].PlatformFormat = DXGI_FORMAT_R16G16_FLOAT; GPixelFormats[ PF_G16R16F_FILTER].PlatformFormat = DXGI_FORMAT_R16G16_FLOAT; GPixelFormats[ PF_G32R32F ].PlatformFormat = DXGI_FORMAT_R32G32_FLOAT; GPixelFormats[ PF_A2B10G10R10 ].PlatformFormat = DXGI_FORMAT_R10G10B10A2_UNORM; GPixelFormats[ PF_A16B16G16R16 ].PlatformFormat = DXGI_FORMAT_R16G16B16A16_UNORM; GPixelFormats[ PF_D24 ].PlatformFormat = DXGI_FORMAT_R24G8_TYPELESS; GPixelFormats[ PF_R16F ].PlatformFormat = DXGI_FORMAT_R16_FLOAT; GPixelFormats[ PF_R16F_FILTER ].PlatformFormat = DXGI_FORMAT_R16_FLOAT; GPixelFormats[ PF_FloatRGB ].PlatformFormat = DXGI_FORMAT_R11G11B10_FLOAT; GPixelFormats[ PF_FloatRGB ].BlockBytes = 4; GPixelFormats[ PF_FloatRGBA ].PlatformFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; GPixelFormats[ PF_FloatRGBA ].BlockBytes = 8; GPixelFormats[ PF_FloatR11G11B10].PlatformFormat = DXGI_FORMAT_R11G11B10_FLOAT; GPixelFormats[ PF_FloatR11G11B10].BlockBytes = 4; GPixelFormats[ PF_V8U8 ].PlatformFormat = DXGI_FORMAT_R8G8_SNORM; GPixelFormats[ PF_BC5 ].PlatformFormat = DXGI_FORMAT_BC5_UNORM; GPixelFormats[ PF_A1 ].PlatformFormat = DXGI_FORMAT_R1_UNORM; // Not supported for rendering. GPixelFormats[ PF_A8 ].PlatformFormat = DXGI_FORMAT_A8_UNORM; GPixelFormats[ PF_R32_UINT ].PlatformFormat = DXGI_FORMAT_R32_UINT; GPixelFormats[ PF_R32_SINT ].PlatformFormat = DXGI_FORMAT_R32_SINT; GPixelFormats[ PF_R16_UINT ].PlatformFormat = DXGI_FORMAT_R16_UINT; GPixelFormats[ PF_R16_SINT ].PlatformFormat = DXGI_FORMAT_R16_SINT; GPixelFormats[ PF_R16G16B16A16_UINT].PlatformFormat = DXGI_FORMAT_R16G16B16A16_UINT; GPixelFormats[ PF_R16G16B16A16_SINT].PlatformFormat = DXGI_FORMAT_R16G16B16A16_SINT; GPixelFormats[ PF_R5G6B5_UNORM ].PlatformFormat = DXGI_FORMAT_B5G6R5_UNORM; GPixelFormats[ PF_R8G8B8A8 ].PlatformFormat = DXGI_FORMAT_R8G8B8A8_TYPELESS; GPixelFormats[ PF_R8G8 ].PlatformFormat = DXGI_FORMAT_R8G8_UNORM; GPixelFormats[ PF_R32G32B32A32_UINT].PlatformFormat = DXGI_FORMAT_R32G32B32A32_UINT; GPixelFormats[ PF_R16G16_UINT].PlatformFormat = DXGI_FORMAT_R16G16_UINT; GPixelFormats[ PF_BC6H ].PlatformFormat = DXGI_FORMAT_BC6H_UF16; GPixelFormats[ PF_BC7 ].PlatformFormat = DXGI_FORMAT_BC7_TYPELESS; // MS - Not doing any feature level checks. D3D12 currently supports these limits. // However this may need to be revisited if new feature levels are introduced with different HW requirement GSupportsSeparateRenderTargetBlendState = true; GMaxTextureDimensions = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; GMaxCubeTextureDimensions = D3D12_REQ_TEXTURECUBE_DIMENSION; GMaxTextureArrayLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; GMaxShadowDepthBufferSizeX = 4096; GMaxShadowDepthBufferSizeY = 4096; // Enable multithreading if not in the editor (editor crashes with multithreading enabled). if (!GIsEditor) { GRHISupportsRHIThread = true; } GRHISupportsParallelRHIExecute = D3D12_SUPPORTS_PARALLEL_RHI_EXECUTE; }
void FAnimNode_AnimDynamics::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { SCOPE_CYCLE_COUNTER(STAT_AnimDynamicsOverall); int32 RestrictToLOD = CVarRestrictLod.GetValueOnAnyThread(); bool bEnabledForLod = RestrictToLOD >= 0 ? SkelComp->PredictedLODLevel == RestrictToLOD : true; if (CVarEnableDynamics.GetValueOnAnyThread() == 1 && bEnabledForLod) { // Pretty nasty - but there isn't really a good way to get clean bone transforms (without the modification from // previous runs) so we have to initialize here, checking often so we can restart a simulation in the editor. if (bRequiresInit) { InitPhysics(SkelComp, MeshBases); bRequiresInit = false; } if (bDoUpdate && NextTimeStep > 0.0f) { // Wind / Force update if(CVarEnableWind.GetValueOnAnyThread() == 1 && bEnableWind) { SCOPE_CYCLE_COUNTER(STAT_AnimDynamicsWindData); for(FAnimPhysRigidBody* Body : BaseBodyPtrs) { if(SkelComp && SkelComp->GetWorld()) { Body->bWindEnabled = bEnableWind; if(Body->bWindEnabled) { UWorld* World = SkelComp->GetWorld(); FSceneInterface* Scene = World->Scene; // Unused by our simulation but needed for the call to GetWindParameters below float WindMinGust; float WindMaxGust; // Setup wind data Body->bWindEnabled = true; Scene->GetWindParameters(SkelComp->ComponentToWorld.TransformPosition(Body->Pose.Position), Body->WindData.WindDirection, Body->WindData.WindSpeed, WindMinGust, WindMaxGust); Body->WindData.WindDirection = SkelComp->ComponentToWorld.Inverse().TransformVector(Body->WindData.WindDirection); Body->WindData.WindAdaption = FMath::FRandRange(0.0f, 2.0f); Body->WindData.BodyWindScale = WindScale; } } } } else { SCOPE_CYCLE_COUNTER(STAT_AnimDynamicsWindData); // Disable wind. for(FAnimPhysRigidBody* Body : BaseBodyPtrs) { Body->bWindEnabled = false; } } if (CVarEnableAdaptiveSubstep.GetValueOnAnyThread() == 1) { float FixedTimeStep = MaxSubstepDeltaTime * CurrentTimeDilation; // Clamp the fixed timestep down to max physics tick time. // at high speeds the simulation will not converge as the delta time is too high, this will // help to keep constraints together at a cost of physical accuracy FixedTimeStep = FMath::Clamp(FixedTimeStep, 0.0f, MaxPhysicsDeltaTime); // Calculate number of substeps we should do. int32 NumIters = FMath::TruncToInt((NextTimeStep + (TimeDebt * CurrentTimeDilation)) / FixedTimeStep); NumIters = FMath::Clamp(NumIters, 0, MaxSubsteps); SET_DWORD_STAT(STAT_AnimDynamicsSubSteps, NumIters); // Store the remaining time as debt for later frames TimeDebt = (NextTimeStep + TimeDebt) - (NumIters * FixedTimeStep); TimeDebt = FMath::Clamp(TimeDebt, 0.0f, MaxTimeDebt); NextTimeStep = FixedTimeStep; for (int32 Iter = 0; Iter < NumIters; ++Iter) { UpdateLimits(SkelComp, MeshBases); FAnimPhys::PhysicsUpdate(FixedTimeStep, BaseBodyPtrs, LinearLimits, AngularLimits, Springs, NumSolverIterationsPreUpdate, NumSolverIterationsPostUpdate); } } else { // Do variable frame-time update const float MaxDeltaTime = MaxPhysicsDeltaTime; NextTimeStep = FMath::Min(NextTimeStep, MaxDeltaTime); UpdateLimits(SkelComp, MeshBases); FAnimPhys::PhysicsUpdate(NextTimeStep, BaseBodyPtrs, LinearLimits, AngularLimits, Springs, NumSolverIterationsPreUpdate, NumSolverIterationsPostUpdate); } } if (bDoEval) { SCOPE_CYCLE_COUNTER(STAT_AnimDynamicsBoneEval); const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); for (int32 Idx = 0; Idx < BoundBoneReferences.Num(); ++Idx) { FBoneReference& CurrentChainBone = BoundBoneReferences[Idx]; FAnimPhysRigidBody& CurrentBody = Bodies[Idx].RigidBody.PhysBody; // Skip invalid bones if(!CurrentChainBone.IsValid(BoneContainer)) { continue; } FCompactPoseBoneIndex BoneIndex = CurrentChainBone.GetCompactPoseIndex(BoneContainer); FTransform NewBoneTransform(CurrentBody.Pose.Orientation, CurrentBody.Pose.Position + CurrentBody.Pose.Orientation.RotateVector(JointOffsets[Idx])); OutBoneTransforms.Add(FBoneTransform(BoneIndex, NewBoneTransform)); } } } }
bool UseSelectiveBasePassOutputs() { return CVarSelectiveBasePassOutputs.GetValueOnAnyThread() == 1; }
void FAndroidOpenGL::ProcessExtensions(const FString& ExtensionsString) { FOpenGLES2::ProcessExtensions(ExtensionsString); FString VersionString = FString(ANSI_TO_TCHAR((const ANSICHAR*)glGetString(GL_VERSION))); bES30Support = VersionString.Contains(TEXT("OpenGL ES 3.")); // Get procedures if (bSupportsOcclusionQueries || bSupportsDisjointTimeQueries) { glGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) ((void*)eglGetProcAddress("glGenQueriesEXT")); glDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) ((void*)eglGetProcAddress("glDeleteQueriesEXT")); glIsQueryEXT = (PFNGLISQUERYEXTPROC) ((void*)eglGetProcAddress("glIsQueryEXT")); glBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) ((void*)eglGetProcAddress("glBeginQueryEXT")); glEndQueryEXT = (PFNGLENDQUERYEXTPROC) ((void*)eglGetProcAddress("glEndQueryEXT")); glGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) ((void*)eglGetProcAddress("glGetQueryivEXT")); glGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC) ((void*)eglGetProcAddress("glGetQueryObjectivEXT")); glGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC)((void*)eglGetProcAddress("glGetQueryObjectuivEXT")); } if (bSupportsDisjointTimeQueries) { glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC) ((void*)eglGetProcAddress("glQueryCounterEXT")); glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) ((void*)eglGetProcAddress("glGetQueryObjectui64vEXT")); // If EXT_disjoint_timer_query wasn't found, NV_timer_query might be available if (glQueryCounterEXT == NULL) { glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC)eglGetProcAddress("glQueryCounterNV"); } if (glGetQueryObjectui64vEXT == NULL) { glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)eglGetProcAddress("glGetQueryObjectui64vNV"); } } glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)((void*)eglGetProcAddress("glDiscardFramebufferEXT")); glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)((void*)eglGetProcAddress("glFramebufferTexture2DMultisampleEXT")); glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)((void*)eglGetProcAddress("glRenderbufferStorageMultisampleEXT")); glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)((void*)eglGetProcAddress("glPushGroupMarkerEXT")); glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)((void*)eglGetProcAddress("glPopGroupMarkerEXT")); glLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC)((void*)eglGetProcAddress("glLabelObjectEXT")); glGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC)((void*)eglGetProcAddress("glGetObjectLabelEXT")); bSupportsETC2 = bES30Support; bUseES30ShadingLanguage = bES30Support; FString RendererString = FString(ANSI_TO_TCHAR((const ANSICHAR*)glGetString(GL_RENDERER))); if (RendererString.Contains(TEXT("SGX 540"))) { UE_LOG(LogRHI, Warning, TEXT("Disabling support for GL_OES_packed_depth_stencil on SGX 540")); bSupportsPackedDepthStencil = false; bRequiresTexture2DPrecisionHack = true; } const bool bIsAdrenoBased = RendererString.Contains(TEXT("Adreno")); if (bIsAdrenoBased) { // This is to avoid a bug in Adreno drivers that define GL_EXT_shader_framebuffer_fetch even when device does not support this extension // OpenGL ES 3.1 [email protected] (GIT@I1af360237c) bRequiresShaderFramebufferFetchUndef = !bSupportsShaderFramebufferFetch; bRequiresARMShaderFramebufferFetchDepthStencilUndef = !bSupportsShaderDepthStencilFetch; // Adreno 2xx doesn't work with packed depth stencil enabled if (RendererString.Contains(TEXT("Adreno (TM) 2"))) { UE_LOG(LogRHI, Warning, TEXT("Disabling support for GL_OES_packed_depth_stencil on Adreno 2xx")); bSupportsPackedDepthStencil = false; } } if (bES30Support) { glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)((void*)eglGetProcAddress("glDrawElementsInstanced")); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)((void*)eglGetProcAddress("glDrawArraysInstanced")); glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)((void*)eglGetProcAddress("glVertexAttribDivisor")); bSupportsInstancing = true; } if (bES30Support || bIsAdrenoBased) { // Attempt to find ES 3.0 glTexStorage2D if we're on an ES 3.0 device glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)((void*)eglGetProcAddress("glTexStorage2D")); if( glTexStorage2D != NULL ) { bUseHalfFloatTexStorage = true; } else { // need to disable GL_EXT_color_buffer_half_float support because we have no way to allocate the storage and the driver doesn't work without it. UE_LOG(LogRHI,Warning,TEXT("Disabling support for GL_EXT_color_buffer_half_float as we cannot bind glTexStorage2D")); bSupportsColorBufferHalfFloat = false; } } //@todo android: need GMSAAAllowed ? if (bSupportsNVFrameBufferBlit) { glBlitFramebufferNV = (PFNBLITFRAMEBUFFERNVPROC)((void*)eglGetProcAddress("glBlitFramebufferNV")); } glMapBufferOES = (PFNGLMAPBUFFEROESPROC)((void*)eglGetProcAddress("glMapBufferOES")); glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC)((void*)eglGetProcAddress("glUnmapBufferOES")); //On Android, there are problems compiling shaders with textureCubeLodEXT calls in the glsl code, // so we set this to false to modify the glsl manually at compile-time. bSupportsTextureCubeLodEXT = false; // On some Android devices with Mali GPUs textureCubeLod is not available. if (RendererString.Contains(TEXT("Mali-400"))) { bSupportsShaderTextureCubeLod = false; } // Nexus 5 (Android 4.4.2) doesn't like glVertexAttribDivisor(index, 0) called when not using a glDrawElementsInstanced if (bIsAdrenoBased && VersionString.Contains(TEXT("OpenGL ES 3.0 [email protected] AU@ (CL@)"))) { UE_LOG(LogRHI, Warning, TEXT("Disabling support for hardware instancing on Adreno 330 OpenGL ES 3.0 [email protected] AU@ (CL@)")); bSupportsInstancing = false; } if (bSupportsBGRA8888 && CVarAndroidDisableTextureFormatBGRA8888.GetValueOnAnyThread() == 1) { UE_LOG(LogRHI, Warning, TEXT("Disabling support for GL_EXT_texture_format_BGRA8888")); bSupportsBGRA8888 = false; } }
void FAnimNode_AimOffsetLookAt::UpdateFromLookAtTarget(FPoseContext& LocalPoseContext) { const FBoneContainer& RequiredBones = LocalPoseContext.Pose.GetBoneContainer(); if (RequiredBones.GetSkeletalMeshAsset()) { const USkeletalMeshSocket* Socket = RequiredBones.GetSkeletalMeshAsset()->FindSocket(SourceSocketName); if (Socket) { const FTransform SocketLocalTransform = Socket->GetSocketLocalTransform(); FBoneReference SocketBoneReference; SocketBoneReference.BoneName = Socket->BoneName; SocketBoneReference.Initialize(RequiredBones); if (SocketBoneReference.IsValid(RequiredBones)) { const FCompactPoseBoneIndex SocketBoneIndex = SocketBoneReference.GetCompactPoseIndex(RequiredBones); FCSPose<FCompactPose> GlobalPose; GlobalPose.InitPose(LocalPoseContext.Pose); USkeletalMeshComponent* Component = LocalPoseContext.AnimInstanceProxy->GetSkelMeshComponent(); AActor* Actor = Component ? Component->GetOwner() : nullptr; if (Component && Actor && BlendSpace) { const FTransform ActorTransform = Actor->GetTransform(); const FTransform BoneTransform = GlobalPose.GetComponentSpaceTransform(SocketBoneIndex); const FTransform SocketWorldTransform = SocketLocalTransform * BoneTransform * Component->ComponentToWorld; // Convert Target to Actor Space const FTransform TargetWorldTransform(LookAtLocation); const FVector DirectionToTarget = ActorTransform.InverseTransformVectorNoScale(TargetWorldTransform.GetLocation() - SocketWorldTransform.GetLocation()).GetSafeNormal(); const FVector CurrentDirection = ActorTransform.InverseTransformVectorNoScale(SocketWorldTransform.GetUnitAxis(EAxis::X)); const FVector AxisX = FVector::ForwardVector; const FVector AxisY = FVector::RightVector; const FVector AxisZ = FVector::UpVector; const FVector2D CurrentCoords = FMath::GetAzimuthAndElevation(CurrentDirection, AxisX, AxisY, AxisZ); const FVector2D TargetCoords = FMath::GetAzimuthAndElevation(DirectionToTarget, AxisX, AxisY, AxisZ); const FVector BlendInput( FRotator::NormalizeAxis(FMath::RadiansToDegrees(TargetCoords.X - CurrentCoords.X)), FRotator::NormalizeAxis(FMath::RadiansToDegrees(TargetCoords.Y - CurrentCoords.Y)), 0.f); // Set X and Y, so ticking next frame is based on correct weights. X = BlendInput.X; Y = BlendInput.Y; // Generate BlendSampleDataCache from inputs. BlendSpace->GetSamplesFromBlendInput(BlendInput, BlendSampleDataCache); if (CVarAimOffsetLookAtDebug.GetValueOnAnyThread() == 1) { DrawDebugLine(Component->GetWorld(), SocketWorldTransform.GetLocation(), TargetWorldTransform.GetLocation(), FColor::Green); DrawDebugLine(Component->GetWorld(), SocketWorldTransform.GetLocation(), SocketWorldTransform.GetLocation() + SocketWorldTransform.GetUnitAxis(EAxis::X) * (TargetWorldTransform.GetLocation() - SocketWorldTransform.GetLocation()).Size(), FColor::Red); DrawDebugCoordinateSystem(Component->GetWorld(), ActorTransform.GetLocation(), ActorTransform.GetRotation().Rotator(), 100.f); FString DebugString = FString::Printf(TEXT("Socket (X:%f, Y:%f), Target (X:%f, Y:%f), Result (X:%f, Y:%f)") , FMath::RadiansToDegrees(CurrentCoords.X) , FMath::RadiansToDegrees(CurrentCoords.Y) , FMath::RadiansToDegrees(TargetCoords.X) , FMath::RadiansToDegrees(TargetCoords.Y) , BlendInput.X , BlendInput.Y); GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0.f, FColor::Red, DebugString, false); } } } } } }
FMeshElementCollector::FMeshElementCollector() : PrimitiveSceneProxy(NULL), FeatureLevel(ERHIFeatureLevel::Num), bUseAsyncTasks(FApp::ShouldUseThreadingForPerformance() && CVarUseParallelGetDynamicMeshElementsTasks.GetValueOnAnyThread() > 0) { }
FSceneView::FSceneView(const FSceneViewInitOptions& InitOptions) : Family(InitOptions.ViewFamily) , State(InitOptions.SceneViewStateInterface) , ViewActor(InitOptions.ViewActor) , Drawer(InitOptions.ViewElementDrawer) , ViewRect(InitOptions.GetConstrainedViewRect()) , UnscaledViewRect(InitOptions.GetConstrainedViewRect()) , UnconstrainedViewRect(InitOptions.GetViewRect()) , MaxShadowCascades(10) , WorldToMetersScale(InitOptions.WorldToMetersScale) , ProjectionMatrixUnadjustedForRHI(InitOptions.ProjectionMatrix) , BackgroundColor(InitOptions.BackgroundColor) , OverlayColor(InitOptions.OverlayColor) , ColorScale(InitOptions.ColorScale) , StereoPass(InitOptions.StereoPass) , DiffuseOverrideParameter(FVector4(0,0,0,1)) , SpecularOverrideParameter(FVector4(0,0,0,1)) , NormalOverrideParameter(FVector4(0,0,0,1)) , RoughnessOverrideParameter(FVector2D(0,1)) , HiddenPrimitives(InitOptions.HiddenPrimitives) , LODDistanceFactor(InitOptions.LODDistanceFactor) , bCameraCut(InitOptions.bInCameraCut) , bOriginOffsetThisFrame(InitOptions.bOriginOffsetThisFrame) , CursorPos(InitOptions.CursorPos) , bIsGameView(false) , bForceShowMaterials(false) , bIsViewInfo(false) , bIsSceneCapture(false) , bIsReflectionCapture(false) , bIsLocked(false) , bStaticSceneOnly(false) #if WITH_EDITOR , OverrideLODViewOrigin(InitOptions.OverrideLODViewOrigin) , bAllowTranslucentPrimitivesInHitProxy( true ) , bHasSelectedComponents( false ) #endif , FeatureLevel(InitOptions.ViewFamily ? InitOptions.ViewFamily->GetFeatureLevel() : GMaxRHIFeatureLevel) { check(UnscaledViewRect.Min.X >= 0); check(UnscaledViewRect.Min.Y >= 0); check(UnscaledViewRect.Width() > 0); check(UnscaledViewRect.Height() > 0); ViewMatrices.ViewMatrix = InitOptions.ViewMatrix; // Adjust the projection matrix for the current RHI. ViewMatrices.ProjMatrix = AdjustProjectionMatrixForRHI(ProjectionMatrixUnadjustedForRHI); // Compute the view projection matrix and its inverse. ViewProjectionMatrix = ViewMatrices.GetViewProjMatrix(); // For precision reasons the view matrix inverse is calculated independently. InvViewMatrix = ViewMatrices.ViewMatrix.Inverse(); InvViewProjectionMatrix = ViewMatrices.GetInvProjMatrix() * InvViewMatrix; bool ApplyPreViewTranslation = true; // Calculate the view origin from the view/projection matrices. if(IsPerspectiveProjection()) { ViewMatrices.ViewOrigin = InvViewMatrix.GetOrigin(); } #if WITH_EDITOR else if (InitOptions.bUseFauxOrthoViewPos) { float DistanceToViewOrigin = WORLD_MAX; ViewMatrices.ViewOrigin = FVector4(InvViewMatrix.TransformVector(FVector(0,0,-1)).GetSafeNormal()*DistanceToViewOrigin,1) + InvViewMatrix.GetOrigin(); } #endif else { ViewMatrices.ViewOrigin = FVector4(InvViewMatrix.TransformVector(FVector(0,0,-1)).GetSafeNormal(),0); // to avoid issues with view dependent effect (e.g. Frensel) ApplyPreViewTranslation = false; } // Translate world-space so its origin is at ViewOrigin for improved precision. // Note that this isn't exactly right for orthogonal projections (See the above special case), but we still use ViewOrigin // in that case so the same value may be used in shaders for both the world-space translation and the camera's world position. if(ApplyPreViewTranslation) { ViewMatrices.PreViewTranslation = -FVector(ViewMatrices.ViewOrigin); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { // console variable override static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PreViewTranslation")); int32 Value = CVar->GetValueOnGameThread(); static FVector PreViewTranslationBackup; if(Value) { PreViewTranslationBackup = ViewMatrices.PreViewTranslation; } else { ViewMatrices.PreViewTranslation = PreViewTranslationBackup; } } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) } /** The view transform, starting from world-space points translated by -ViewOrigin. */ FMatrix TranslatedViewMatrix = FTranslationMatrix(-ViewMatrices.PreViewTranslation) * ViewMatrices.ViewMatrix; // Compute a transform from view origin centered world-space to clip space. ViewMatrices.TranslatedViewProjectionMatrix = TranslatedViewMatrix * ViewMatrices.ProjMatrix; ViewMatrices.InvTranslatedViewProjectionMatrix = ViewMatrices.TranslatedViewProjectionMatrix.Inverse(); // Compute screen scale factors. // Stereo renders at half horizontal resolution, but compute shadow resolution based on full resolution. const bool bStereo = StereoPass != eSSP_FULL; const float ScreenXScale = bStereo ? 2.0f : 1.0f; ViewMatrices.ProjectionScale.X = ScreenXScale * FMath::Abs(ViewMatrices.ProjMatrix.M[0][0]); ViewMatrices.ProjectionScale.Y = FMath::Abs(ViewMatrices.ProjMatrix.M[1][1]); ViewMatrices.ScreenScale = FMath::Max( ViewRect.Size().X * 0.5f * ViewMatrices.ProjectionScale.X, ViewRect.Size().Y * 0.5f * ViewMatrices.ProjectionScale.Y ); ShadowViewMatrices = ViewMatrices; #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { // console variable override int32 Value = CVarShadowFreezeCamera.GetValueOnAnyThread(); static FViewMatrices Backup = ShadowViewMatrices; if(Value) { ShadowViewMatrices = Backup; } else { Backup = ShadowViewMatrices; } } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (InitOptions.OverrideFarClippingPlaneDistance > 0.0f) { const FPlane FarPlane(ViewMatrices.ViewOrigin + GetViewDirection() * InitOptions.OverrideFarClippingPlaneDistance, GetViewDirection()); // Derive the view frustum from the view projection matrix, overriding the far plane GetViewFrustumBounds(ViewFrustum,ViewProjectionMatrix,FarPlane,true,false); } else { // Derive the view frustum from the view projection matrix. GetViewFrustumBounds(ViewFrustum,ViewProjectionMatrix,false); } // Derive the view's near clipping distance and plane. // The GetFrustumFarPlane() is the near plane because of reverse Z projection. bHasNearClippingPlane = ViewProjectionMatrix.GetFrustumFarPlane(NearClippingPlane); if(ViewMatrices.ProjMatrix.M[2][3] > DELTA) { // Infinite projection with reversed Z. NearClippingDistance = ViewMatrices.ProjMatrix.M[3][2]; } else { // Ortho projection with reversed Z. NearClippingDistance = (1.0f - ViewMatrices.ProjMatrix.M[3][2]) / ViewMatrices.ProjMatrix.M[2][2]; } // Determine whether the view should reverse the cull mode due to a negative determinant. Only do this for a valid scene bReverseCulling = (Family && Family->Scene) ? FMath::IsNegativeFloat(ViewMatrices.ViewMatrix.Determinant()) : false; // OpenGL Gamma space output in GLSL flips Y when rendering directly to the back buffer (so not needed on PC, as we never render directly into the back buffer) auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel]; static bool bPlatformRequiresReverseCulling = (IsOpenGLPlatform(ShaderPlatform) && !IsPCPlatform(ShaderPlatform)); static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR")); check(MobileHDRCvar); bReverseCulling = (bPlatformRequiresReverseCulling && MobileHDRCvar->GetValueOnAnyThread() == 0) ? !bReverseCulling : bReverseCulling; // Setup transformation constants to be used by the graphics hardware to transform device normalized depth samples // into world oriented z. InvDeviceZToWorldZTransform = CreateInvDeviceZToWorldZTransform(ProjectionMatrixUnadjustedForRHI); static TConsoleVariableData<int32>* SortPolicyCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.TranslucentSortPolicy")); TranslucentSortPolicy = static_cast<ETranslucentSortPolicy::Type>(SortPolicyCvar->GetValueOnAnyThread()); TranslucentSortAxis = GetDefault<URendererSettings>()->TranslucentSortAxis; // As the world is only accessable from the game thread, bIsGameView should be explicitly // set on any other thread. if(IsInGameThread()) { bIsGameView = (Family && Family->Scene && Family->Scene->GetWorld() ) ? Family->Scene->GetWorld()->IsGameWorld() : false; } #if WITH_EDITOR EditorViewBitflag = InitOptions.EditorViewBitflag; SelectionOutlineColor = GEngine->GetSelectionOutlineColor(); #endif }
bool FCompositionLighting::IsSubsurfacePostprocessRequired() const { const bool bSSSEnabled = CVarSubsurfaceScattering->GetInt() != 0; const bool bSSSScaleEnabled = CVarSSSScale.GetValueOnAnyThread() > 0.0f; return (bSSSEnabled && bSSSScaleEnabled); }
/** Util to convert an overlapped shape into a sweep hit result, returns whether it was a blocking hit. */ static bool ConvertOverlappedShapeToImpactHit(const UWorld* World, const PxLocationHit& PHit, const FVector& StartLoc, const FVector& EndLoc, FHitResult& OutResult, const PxGeometry& Geom, const PxTransform& QueryTM, const PxFilterData& QueryFilter, bool bReturnPhysMat) { SCOPE_CYCLE_COUNTER(STAT_CollisionConvertOverlapToHit); const PxShape* PShape = PHit.shape; const PxRigidActor* PActor = PHit.actor; const uint32 FaceIdx = PHit.faceIndex; // See if this is a 'blocking' hit PxFilterData PShapeFilter = PShape->getQueryFilterData(); PxSceneQueryHitType::Enum HitType = FPxQueryFilterCallback::CalcQueryHitType(QueryFilter, PShapeFilter); const bool bBlockingHit = (HitType == PxSceneQueryHitType::eBLOCK); OutResult.bBlockingHit = bBlockingHit; // Time of zero because initially overlapping OutResult.bStartPenetrating = true; OutResult.Time = 0.f; OutResult.Distance = 0.f; // Return start location as 'safe location' OutResult.Location = P2UVector(QueryTM.p); OutResult.ImpactPoint = OutResult.Location; // @todo not really sure of a better thing to do here... OutResult.TraceStart = StartLoc; OutResult.TraceEnd = EndLoc; const bool bFiniteNormal = PHit.normal.isFinite(); const bool bValidNormal = (PHit.flags & PxHitFlag::eNORMAL) && bFiniteNormal; // Use MTD result if possible. We interpret the MTD vector as both the direction to move and the opposing normal. if (bValidNormal) { OutResult.ImpactNormal = P2UVector(PHit.normal); OutResult.PenetrationDepth = FMath::Abs(PHit.distance); } else { // Fallback normal if we can't find it with MTD or otherwise. OutResult.ImpactNormal = FVector::UpVector; OutResult.PenetrationDepth = 0.f; if (!bFiniteNormal) { UE_LOG(LogPhysics, Verbose, TEXT("Warning: ConvertOverlappedShapeToImpactHit: MTD returned NaN :( normal: (X:%f, Y:%f, Z:%f)"), PHit.normal.x, PHit.normal.y, PHit.normal.z); } } #if DRAW_OVERLAPPING_TRIS if (CVarShowInitialOverlaps.GetValueOnAnyThread() != 0 && World && World->IsGameWorld()) { FVector DummyNormal(0.f); const PxTransform PShapeWorldPose = PxShapeExt::getGlobalPose(*PShape, *PActor); FindOverlappedTriangleNormal(World, Geom, QueryTM, PShape, PShapeWorldPose, DummyNormal, 0.f, true); } #endif if (bBlockingHit) { // Zero-distance hits are often valid hits and we can extract the hit normal. // For invalid normals we can try other methods as well (get overlapping triangles). if (PHit.distance == 0.f || !bValidNormal) { const PxTransform PShapeWorldPose = PxShapeExt::getGlobalPose(*PShape, *PActor); // Try MTD with a small inflation for better accuracy, then a larger one in case the first one fails due to precision issues. static const float SmallMtdInflation = 0.250f; static const float LargeMtdInflation = 1.750f; if (ComputeInflatedMTD(SmallMtdInflation, PHit, OutResult, QueryTM, Geom, PShapeWorldPose) || ComputeInflatedMTD(LargeMtdInflation, PHit, OutResult, QueryTM, Geom, PShapeWorldPose)) { // Success } else { static const float SmallOverlapInflation = 0.250f; if (FindOverlappedTriangleNormal(World, Geom, QueryTM, PShape, PShapeWorldPose, OutResult.ImpactNormal, 0.f, false) || FindOverlappedTriangleNormal(World, Geom, QueryTM, PShape, PShapeWorldPose, OutResult.ImpactNormal, SmallOverlapInflation, false)) { // Success } else { // MTD failed, use point distance. This is not ideal. // Note: faceIndex seems to be unreliable for convex meshes in these cases, so not using FindGeomOpposingNormal() for them here. PxGeometry& PGeom = PShape->getGeometry().any(); PxVec3 PClosestPoint; const float Distance = PxGeometryQuery::pointDistance(QueryTM.p, PGeom, PShapeWorldPose, &PClosestPoint); if (Distance < KINDA_SMALL_NUMBER) { UE_LOG(LogCollision, Verbose, TEXT("Warning: ConvertOverlappedShapeToImpactHit: Query origin inside shape, giving poor MTD.")); PClosestPoint = PxShapeExt::getWorldBounds(*PShape, *PActor).getCenter(); } OutResult.ImpactNormal = (OutResult.Location - P2UVector(PClosestPoint)).GetSafeNormal(); } } } } else { // non blocking hit (overlap). if (!bValidNormal) { OutResult.ImpactNormal = (StartLoc - EndLoc).GetSafeNormal(); ensure(OutResult.ImpactNormal.IsNormalized()); } } OutResult.Normal = OutResult.ImpactNormal; SetHitResultFromShapeAndFaceIndex(PShape, PActor, FaceIdx, OutResult, bReturnPhysMat); return bBlockingHit; }
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); } } }