bool FShaderResource::ArePlatformsCompatible(EShaderPlatform CurrentPlatform, EShaderPlatform TargetPlatform) { bool bFeatureLevelCompatible = CurrentPlatform == TargetPlatform; if (!bFeatureLevelCompatible && IsPCPlatform(CurrentPlatform) && IsPCPlatform(TargetPlatform) ) { if (CurrentPlatform == SP_OPENGL_SM4_MAC || TargetPlatform == SP_OPENGL_SM4_MAC) { // prevent SP_OPENGL_SM4 == SP_OPENGL_SM4_MAC, allow SP_OPENGL_SM4_MAC == SP_OPENGL_SM4_MAC, // allow lesser feature levels on SP_OPENGL_SM4_MAC device. // do not allow MAC targets to work on non MAC devices. bFeatureLevelCompatible = CurrentPlatform == SP_OPENGL_SM4_MAC && GetMaxSupportedFeatureLevel(CurrentPlatform) >= GetMaxSupportedFeatureLevel(TargetPlatform); } else { bFeatureLevelCompatible = GetMaxSupportedFeatureLevel(CurrentPlatform) >= GetMaxSupportedFeatureLevel(TargetPlatform); } bool bIsTargetD3D = TargetPlatform == SP_PCD3D_SM5 || TargetPlatform == SP_PCD3D_SM4 || TargetPlatform == SP_PCD3D_ES3_1 || TargetPlatform == SP_PCD3D_ES2; bool bIsCurrentPlatformD3D = CurrentPlatform == SP_PCD3D_SM5 || CurrentPlatform == SP_PCD3D_SM4 || TargetPlatform == SP_PCD3D_ES3_1 || CurrentPlatform == SP_PCD3D_ES2; bFeatureLevelCompatible = bFeatureLevelCompatible && (bIsCurrentPlatformD3D == bIsTargetD3D); } return bFeatureLevelCompatible; }
void FForwardShadingSceneRenderer::ConditionalResolveSceneDepth(FRHICommandListImmediate& RHICmdList) { FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); SceneContext.ResolveSceneDepthToAuxiliaryTexture(RHICmdList); #if !PLATFORM_HTML5 auto ShaderPlatform = ViewFamily.GetShaderPlatform(); if (IsMobilePlatform(ShaderPlatform) && !IsPCPlatform(ShaderPlatform)) // exclude mobile emulation on PC { bool bSceneDepthInAlpha = (SceneContext.GetSceneColor()->GetDesc().Format == PF_FloatRGBA); bool bOnChipDepthFetch = (GSupportsShaderDepthStencilFetch || (bSceneDepthInAlpha && GSupportsShaderFramebufferFetch)); if (!bOnChipDepthFetch) { // Only these features require depth texture bool bDecals = ViewFamily.EngineShowFlags.Decals && Scene->Decals.Num(); bool bModulatedShadows = ViewFamily.EngineShowFlags.DynamicShadows && GetShadowQuality() > 0 && bModulatedShadowsInUse; if (bDecals || bModulatedShadows) { // Switch target to force hardware flush current depth to texture FTextureRHIRef DummySceneColor = GSystemTextures.BlackDummy->GetRenderTargetItem().TargetableTexture; FTextureRHIRef DummyDepthTarget = GSystemTextures.DepthDummy->GetRenderTargetItem().TargetableTexture; SetRenderTarget(RHICmdList, DummySceneColor, DummyDepthTarget, ESimpleRenderTargetMode::EUninitializedColorClearDepth, FExclusiveDepthStencil::DepthWrite_StencilWrite); RHICmdList.DiscardRenderTargets(true, true, 0); } } } #endif //!PLATFORM_HTML5 }
void FOSVRHMD::StartCustomPresent() { #if PLATFORM_WINDOWS if (!mCustomPresent && IsPCPlatform(GMaxRHIShaderPlatform) && !IsOpenGLPlatform(GMaxRHIShaderPlatform)) { // currently, FCustomPresent creates its own client context, so no need to // synchronize with the one from FOSVREntryPoint. mCustomPresent = new FCurrentCustomPresent(nullptr/*osvrClientContext*/); } #endif }
const UShaderPlatformQualitySettings* UMaterialShaderQualitySettings::GetShaderPlatformQualitySettings(EShaderPlatform ShaderPlatform) { #if WITH_EDITORONLY_DATA // TODO: discuss this, in order to preview render quality settings we override the // requested platform's settings. // However we do not know if we are asking for the editor preview window (override able) or for thumbnails, cooking purposes etc.. (Must not override) // The code below 'works' because desktop platforms do not cook for ES2 preview. if (IsPCPlatform(ShaderPlatform) && IsES2Platform(ShaderPlatform)) { // Can check this cant be cooked by iterating through target platforms and shader formats to ensure it's not covered. if (PreviewPlatformSettings != nullptr) { return PreviewPlatformSettings; } } #endif return GetShaderPlatformQualitySettings(GetPlatformNameFromShaderPlatform(ShaderPlatform)); }
bool FDeferredShadingSceneRenderer::RenderBasePassDynamicData(FViewInfo& View) { bool bDirty=0; if( !View.Family->EngineShowFlags.CompositeEditorPrimitives ) { const bool bNeedToSwitchVerticalAxis = IsES2Platform(GRHIShaderPlatform) && !IsPCPlatform(GRHIShaderPlatform); // Draw the base pass for the view's batched mesh elements. bDirty = DrawViewElements<FBasePassOpaqueDrawingPolicyFactory>(View,FBasePassOpaqueDrawingPolicyFactory::ContextType(false, ESceneRenderTargetsMode::DontSet), SDPG_World, true) || bDirty; // Draw the view's batched simple elements(lines, sprites, etc). bDirty = View.BatchedViewElements.Draw(bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false) || bDirty; // Draw foreground objects last bDirty = DrawViewElements<FBasePassOpaqueDrawingPolicyFactory>(View,FBasePassOpaqueDrawingPolicyFactory::ContextType(false, ESceneRenderTargetsMode::DontSet), SDPG_Foreground, true) || bDirty; // Draw the view's batched simple elements(lines, sprites, etc). bDirty = View.TopBatchedViewElements.Draw(bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false) || bDirty; } return bDirty; }
void FForwardShadingSceneRenderer::RenderTranslucency(FRHICommandListImmediate& RHICmdList) { if (ShouldRenderTranslucency()) { const bool bGammaSpace = !IsMobileHDR(); const bool bLinearHDR64 = !bGammaSpace && !IsMobileHDR32bpp(); SCOPED_DRAW_EVENT(RHICmdList, Translucency); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPED_CONDITIONAL_DRAW_EVENTF(RHICmdList, EventView, Views.Num() > 1, TEXT("View%d"), ViewIndex); const FViewInfo& View = Views[ViewIndex]; #if PLATFORM_HTML5 // Copy the view so emulation of framebuffer fetch works for alpha=depth. // Possible optimization: this copy shouldn't be needed unless something uses fetch of depth. if(bLinearHDR64 && GSupportsRenderTargetFormat_PF_FloatRGBA && (GSupportsShaderFramebufferFetch == false) && (!IsPCPlatform(View.GetShaderPlatform()))) { CopySceneAlpha(RHICmdList, View); } #endif if (!bGammaSpace) { GSceneRenderTargets.BeginRenderingTranslucency(RHICmdList, View); } else { RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); } // Enable depth test, disable depth writes. RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false,CF_DepthNearOrEqual>::GetRHI()); // Draw only translucent prims that don't read from scene color View.TranslucentPrimSet.DrawPrimitivesForForwardShading(RHICmdList, View, *this); // Draw the view's mesh elements with the translucent drawing policy. DrawViewElements<FTranslucencyForwardShadingDrawingPolicyFactory>(RHICmdList, View, FTranslucencyForwardShadingDrawingPolicyFactory::ContextType(), SDPG_World, false); // Draw the view's mesh elements with the translucent drawing policy. DrawViewElements<FTranslucencyForwardShadingDrawingPolicyFactory>(RHICmdList, View, FTranslucencyForwardShadingDrawingPolicyFactory::ContextType(), SDPG_Foreground, false); } } }
void FSteamVRHMD::Startup() { // load the OpenVR library if (!LoadOpenVRModule()) { return; } // grab a pointer to the renderer module for displaying our mirror window static const FName RendererModuleName("Renderer"); RendererModule = FModuleManager::GetModulePtr<IRendererModule>(RendererModuleName); vr::HmdError HmdErr = vr::HmdError_None; //VRSystem = vr::VR_Init(&HmdErr); VRSystem = (*VRInitFn)(&HmdErr); // make sure that the version of the HMD we're compiled against is correct if ((VRSystem != nullptr) && (HmdErr == vr::HmdError_None)) { //VRSystem = (vr::IVRSystem*)vr::VR_GetGenericInterface(vr::IVRSystem_Version, &HmdErr); //@todo steamvr: verify init error handling VRSystem = (vr::IVRSystem*)(*VRGetGenericInterfaceFn)(vr::IVRSystem_Version, &HmdErr); } // attach to the compositor if ((VRSystem != nullptr) && (HmdErr == vr::HmdError_None)) { //VRCompositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &HmdErr); VRCompositor = (vr::IVRCompositor*)(*VRGetGenericInterfaceFn)(vr::IVRCompositor_Version, &HmdErr); if ((VRCompositor != nullptr) && (HmdErr == vr::HmdError_None)) { // determine our compositor type vr::Compositor_DeviceType CompositorDeviceType = vr::Compositor_DeviceType_None; if (IsPCPlatform(GMaxRHIShaderPlatform) && !IsOpenGLPlatform(GMaxRHIShaderPlatform)) { CompositorDeviceType = vr::Compositor_DeviceType_D3D11; } else if (IsOpenGLPlatform(GMaxRHIShaderPlatform)) { check(0); //@todo steamvr: use old path for mac and linux until support is added CompositorDeviceType = vr::Compositor_DeviceType_OpenGL; } } } if ((VRSystem != nullptr) && (HmdErr == vr::HmdError_None)) { // grab info about the attached display char Buf[128]; FString DriverId; vr::TrackedPropertyError Error; VRSystem->GetStringTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String, Buf, sizeof(Buf), &Error); if (Error == vr::TrackedProp_Success) { DriverId = FString(UTF8_TO_TCHAR(Buf)); } VRSystem->GetStringTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String, Buf, sizeof(Buf), &Error); if (Error == vr::TrackedProp_Success) { DisplayId = FString(UTF8_TO_TCHAR(Buf)); } // determine our ideal screen percentage uint32 RecommendedWidth, RecommendedHeight; VRSystem->GetRecommendedRenderTargetSize(&RecommendedWidth, &RecommendedHeight); RecommendedWidth *= 2; int32 ScreenX, ScreenY; uint32 ScreenWidth, ScreenHeight; VRSystem->GetWindowBounds(&ScreenX, &ScreenY, &ScreenWidth, &ScreenHeight); float WidthPercentage = ((float)RecommendedWidth / (float)ScreenWidth) * 100.0f; float HeightPercentage = ((float)RecommendedHeight / (float)ScreenHeight) * 100.0f; float ScreenPercentage = FMath::Max(WidthPercentage, HeightPercentage); //@todo steamvr: move out of here static IConsoleVariable* CScrPercVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage")); if (FMath::RoundToInt(CScrPercVar->GetFloat()) != FMath::RoundToInt(ScreenPercentage)) { CScrPercVar->Set(ScreenPercentage); } // disable vsync static IConsoleVariable* CVSyncVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.VSync")); CVSyncVar->Set(false); // enforce finishcurrentframe static IConsoleVariable* CFCFVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.finishcurrentframe")); CFCFVar->Set(false); // Grab the chaperone vr::HmdError ChaperoneErr = vr::HmdError_None; //VRChaperone = (vr::IVRChaperone*)vr::VR_GetGenericInterface(vr::IVRChaperone_Version, &ChaperoneErr); VRChaperone = (vr::IVRChaperone*)(*VRGetGenericInterfaceFn)(vr::IVRChaperone_Version, &ChaperoneErr); if ((VRChaperone != nullptr) && (ChaperoneErr == vr::HmdError_None)) { ChaperoneBounds = FChaperoneBounds(VRChaperone); } else { UE_LOG(LogHMD, Warning, TEXT("Failed to initialize Chaperone. Error: %d"), (int32)ChaperoneErr); } // Initialize our controller to device index for (int32 UnrealControllerIndex = 0; UnrealControllerIndex < MAX_STEAMVR_CONTROLLER_PAIRS; ++UnrealControllerIndex ) { for( int32 HandIndex = 0; HandIndex < 2; ++HandIndex ) { UnrealControllerIdAndHandToDeviceIdMap[ UnrealControllerIndex ][ HandIndex ] = INDEX_NONE; } } #if PLATFORM_WINDOWS if (IsPCPlatform(GMaxRHIShaderPlatform) && !IsOpenGLPlatform(GMaxRHIShaderPlatform)) { pD3D11Bridge = new D3D11Bridge(this); } #endif LoadFromIni(); UE_LOG(LogHMD, Log, TEXT("SteamVR initialized. Driver: %s Display: %s"), *DriverId, *DisplayId); } else { UE_LOG(LogHMD, Log, TEXT("SteamVR failed to initialize. Err: %d"), (int32)HmdErr); VRSystem = nullptr; } // share the IVRSystem interface out to the SteamVRController via the module layer SteamVRPlugin->SetVRSystem(VRSystem); }
bool FCanvasBatchedElementRenderItem::Render( const FCanvas* Canvas ) { checkSlow(Data); bool bDirty=false; if( Data->BatchedElements.HasPrimsToDraw() ) { bDirty = true; // current render target set for the canvas const FRenderTarget* CanvasRenderTarget = Canvas->GetRenderTarget(); float Gamma = 1.0f / CanvasRenderTarget->GetDisplayGamma(); if ( Data->Texture && Data->Texture->bIgnoreGammaConversions ) { Gamma = 1.0f; } // this allows us to use FCanvas operations from the rendering thread (ie, render subtitles // on top of a movie that is rendered completely in rendering thread) if (IsInRenderingThread()) { const bool bNeedsToSwitchVerticalAxis = IsES2Platform(GRHIShaderPlatform) && !IsPCPlatform(GRHIShaderPlatform); // draw batched items Data->BatchedElements.Draw( bNeedsToSwitchVerticalAxis, Data->Transform.GetMatrix(), CanvasRenderTarget->GetSizeXY().X, CanvasRenderTarget->GetSizeXY().Y, Canvas->IsHitTesting(), Gamma ); if( Canvas->GetAllowedModes() & FCanvas::Allow_DeleteOnRender ) { // delete data since we're done rendering it delete Data; } } else { // Render the batched elements. struct FBatchedDrawParameters { FRenderData* RenderData; uint32 bHitTesting : 1; uint32 ViewportSizeX; uint32 ViewportSizeY; float DisplayGamma; uint32 AllowedCanvasModes; }; // all the parameters needed for rendering FBatchedDrawParameters DrawParameters = { Data, Canvas->IsHitTesting(), (uint32)CanvasRenderTarget->GetSizeXY().X, (uint32)CanvasRenderTarget->GetSizeXY().Y, Gamma, Canvas->GetAllowedModes() }; ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER( BatchedDrawCommand, FBatchedDrawParameters,Parameters,DrawParameters, { const bool bNeedsToSwitchVerticalAxis = IsES2Platform(GRHIShaderPlatform) && !IsPCPlatform(GRHIShaderPlatform); // draw batched items Parameters.RenderData->BatchedElements.Draw( bNeedsToSwitchVerticalAxis, Parameters.RenderData->Transform.GetMatrix(), Parameters.ViewportSizeX, Parameters.ViewportSizeY, Parameters.bHitTesting, Parameters.DisplayGamma ); if( Parameters.AllowedCanvasModes & FCanvas::Allow_DeleteOnRender ) { delete Parameters.RenderData; } }); }
void FForwardShadingSceneRenderer::RenderForwardShadingBasePass() { SCOPED_DRAW_EVENT(BasePass, DEC_SCENE_ITEMS); SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime); EBasePassSort::Type SortMode = GetSortMode(); int32 MaxDraws = GMaxBasePassDraws.GetValueOnRenderThread(); if (MaxDraws <= 0) { MaxDraws = MAX_int32; } if (SortMode == EBasePassSort::SortStateBuckets) { SCOPE_CYCLE_COUNTER(STAT_SortStaticDrawLists); for (int32 DrawType = 0; DrawType < FScene::EBasePass_MAX; DrawType++) { Scene->BasePassForForwardShadingLowQualityLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingNoLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); } } // Draw the scene's emissive and light-map color. for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPED_CONDITIONAL_DRAW_EVENTF(EventView, Views.Num() > 1, DEC_SCENE_ITEMS, TEXT("View%d"), ViewIndex); FViewInfo& View = Views[ViewIndex]; // Opaque blending RHISetBlendState(TStaticBlendStateWriteMask<CW_RGBA>::GetRHI()); // Note, this is a reversed Z depth surface, using CF_GreaterEqual. RHISetDepthStencilState(TStaticDepthStencilState<true, CF_GreaterEqual>::GetRHI()); RHISetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1); // Render the base pass static data if (SortMode == EBasePassSort::SortPerMesh) { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); MaxDraws -= Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); } else { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Default].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Default].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Default].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Default].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); } { SCOPE_CYCLE_COUNTER(STAT_DynamicPrimitiveDrawTime); SCOPED_DRAW_EVENT(Dynamic, DEC_SCENE_ITEMS); if (View.VisibleDynamicPrimitives.Num() > 0) { // Draw the dynamic non-occluded primitives using a base pass drawing policy. TDynamicPrimitiveDrawer<FBasePassForwardOpaqueDrawingPolicyFactory> Drawer(&View, FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), true); for (int32 PrimitiveIndex = 0; PrimitiveIndex < View.VisibleDynamicPrimitives.Num(); PrimitiveIndex++) { const FPrimitiveSceneInfo* PrimitiveSceneInfo = View.VisibleDynamicPrimitives[PrimitiveIndex]; int32 PrimitiveId = PrimitiveSceneInfo->GetIndex(); const FPrimitiveViewRelevance& PrimitiveViewRelevance = View.PrimitiveViewRelevanceMap[PrimitiveId]; const bool bVisible = View.PrimitiveVisibilityMap[PrimitiveId]; // Only draw the primitive if it's visible if (bVisible && // only draw opaque and masked primitives if wireframe is disabled (PrimitiveViewRelevance.bOpaqueRelevance || ViewFamily.EngineShowFlags.Wireframe)) { FScopeCycleCounter Context(PrimitiveSceneInfo->Proxy->GetStatId()); Drawer.SetPrimitive(PrimitiveSceneInfo->Proxy); PrimitiveSceneInfo->Proxy->DrawDynamicElements(&Drawer, &View); } } } const bool bNeedToSwitchVerticalAxis = IsES2Platform(GRHIShaderPlatform) && !IsPCPlatform(GRHIShaderPlatform); // Draw the base pass for the view's batched mesh elements. DrawViewElements<FBasePassForwardOpaqueDrawingPolicyFactory>(View,FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), SDPG_World, true); // Draw the view's batched simple elements(lines, sprites, etc). View.BatchedViewElements.Draw(bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false); // Draw foreground objects last DrawViewElements<FBasePassForwardOpaqueDrawingPolicyFactory>(View,FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), SDPG_Foreground, true); // Draw the view's batched simple elements(lines, sprites, etc). View.TopBatchedViewElements.Draw(bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false); } // Issue static draw list masked draw calls last, as PVR wants it if (SortMode == EBasePassSort::SortPerMesh) { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); MaxDraws -= Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); } else { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Masked].DrawVisible(View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); } } }
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 }