void FTemporalLODState::UpdateTemporalLODTransition(const FViewInfo& View, float LastRenderTime) { bool bOk = false; if (!View.bDisableDistanceBasedFadeTransitions) { bOk = true; TemporalLODLag = CVarLODTemporalLag.GetValueOnRenderThread(); if (TemporalLODTime[1] < LastRenderTime - TemporalLODLag) { if (TemporalLODTime[0] < TemporalLODTime[1]) { TemporalLODViewOrigin[0] = TemporalLODViewOrigin[1]; TemporalDistanceFactor[0] = TemporalDistanceFactor[1]; TemporalLODTime[0] = TemporalLODTime[1]; } TemporalLODViewOrigin[1] = View.ViewMatrices.ViewOrigin; TemporalDistanceFactor[1] = View.GetLODDistanceFactor(); TemporalLODTime[1] = LastRenderTime; if (TemporalLODTime[1] <= TemporalLODTime[0]) { bOk = false; // we are paused or something or otherwise didn't get a good sample } } } if (!bOk) { TemporalLODViewOrigin[0] = View.ViewMatrices.ViewOrigin; TemporalLODViewOrigin[1] = View.ViewMatrices.ViewOrigin; TemporalDistanceFactor[0] = View.GetLODDistanceFactor(); TemporalDistanceFactor[1] = TemporalDistanceFactor[0]; TemporalLODTime[0] = LastRenderTime; TemporalLODTime[1] = LastRenderTime; TemporalLODLag = 0.0f; } }
/** * Render a dynamic mesh using a translucent draw policy * @return true if the mesh rendered */ bool FTranslucencyForwardShadingDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { bool bDirty = false; // Determine the mesh's material and blend mode. const auto FeatureLevel = View.GetFeatureLevel(); const auto ShaderPlatform = View.GetShaderPlatform(); const FMaterial* Material = Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel); const EBlendMode BlendMode = Material->GetBlendMode(); // Only render translucent materials. if (IsTranslucentBlendMode(BlendMode)) { const bool bDisableDepthTest = Material->ShouldDisableDepthTest(); if (bDisableDepthTest) { RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); } ProcessBasePassMeshForForwardShading( RHICmdList, FProcessBasePassMeshParameters( Mesh, Material, PrimitiveSceneProxy, true, false, ESceneRenderTargetsMode::SetTextures, FeatureLevel ), FDrawTranslucentMeshForwardShadingAction( View, bBackFace, HitProxyId ) ); if (bDisableDepthTest) { // Restore default depth state // Note, this is a reversed Z depth surface, using CF_GreaterEqual. RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_GreaterEqual>::GetRHI()); } bDirty = true; } return bDirty; }
void FTranslucencyDrawingPolicyFactory::CopySceneColor(FRHICommandList& RHICmdList, const FViewInfo& View, const FPrimitiveSceneProxy* PrimitiveSceneProxy) { SCOPED_DRAW_EVENTF(RHICmdList, EventCopy, TEXT("CopySceneColor for %s %s"), *PrimitiveSceneProxy->GetOwnerName().ToString(), *PrimitiveSceneProxy->GetResourceName().ToString()); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); GSceneRenderTargets.ResolveSceneColor(RHICmdList); GSceneRenderTargets.BeginRenderingLightAttenuation(RHICmdList); RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); TShaderMapRef<FCopySceneColorPS> PixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), CopySceneColorBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *PixelShader); /// ? PixelShader->SetParameters(RHICmdList, View); DrawRectangle( RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(View.ViewRect.Width(), View.ViewRect.Height()), GSceneRenderTargets.GetBufferSizeXY(), *ScreenVertexShader, EDRF_UseTriangleOptimization); GSceneRenderTargets.FinishRenderingLightAttenuation(RHICmdList); }
/** * Render a static mesh using a translucent draw policy * @return true if the mesh rendered */ bool FTranslucencyForwardShadingDrawingPolicyFactory::DrawStaticMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FStaticMesh& StaticMesh, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { bool bDirty = false; const FMaterial* Material = StaticMesh.MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()); bDirty |= DrawDynamicMesh( RHICmdList, View, DrawingContext, StaticMesh, false, bPreFog, PrimitiveSceneProxy, HitProxyId ); return bDirty; }
/** Draws a full view quad that sets stencil to 1 anywhere that decals should not be projected. */ void StencilDecalMask(FRHICommandList& RHICmdList, const FViewInfo& View, bool bUseHmdMesh) { SCOPED_DRAW_EVENT(RHICmdList, StencilDecalMask); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetBlendState(TStaticBlendState<CW_NONE>::GetRHI()); SetRenderTarget(RHICmdList, NULL, SceneContext.GetSceneDepthSurface(), ESimpleRenderTargetMode::EUninitializedColorExistingDepth, FExclusiveDepthStencil::DepthRead_StencilWrite); RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); // Write 1 to highest bit of stencil to areas that should not receive decals RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always, true, CF_Always, SO_Replace, SO_Replace, SO_Replace>::GetRHI(), 0x80); const auto FeatureLevel = View.GetFeatureLevel(); auto ShaderMap = View.ShaderMap; TShaderMapRef<FScreenVS> ScreenVertexShader(ShaderMap); TShaderMapRef<FStencilDecalMaskPS> PixelShader(ShaderMap); SetGlobalBoundShaderState(RHICmdList, FeatureLevel, StencilDecalMaskBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, View); DrawPostProcessPass( RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(View.ViewRect.Width(), View.ViewRect.Height()), SceneContext.GetBufferSizeXY(), *ScreenVertexShader, View.StereoPass, bUseHmdMesh, EDRF_UseTriangleOptimization); }
void FDecalRendering::SetShader(FRHICommandList& RHICmdList, const FViewInfo& View, bool bShaderComplexity, const FTransientDecalRenderData& DecalData, const FMatrix& FrustumComponentToClip) { const FMaterialShaderMap* MaterialShaderMap = DecalData.MaterialResource->GetRenderingThreadShaderMap(); auto PixelShader = MaterialShaderMap->GetShader<FDeferredDecalPS>(); TShaderMapRef<FDeferredDecalVS> VertexShader(View.ShaderMap); if(bShaderComplexity) { TShaderMapRef<FShaderComplexityAccumulatePS> VisualizePixelShader(View.ShaderMap); const uint32 NumPixelShaderInstructions = PixelShader->GetNumInstructions(); const uint32 NumVertexShaderInstructions = VertexShader->GetNumInstructions(); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GetVertexDeclarationFVector4(), *VertexShader, *VisualizePixelShader); VisualizePixelShader->SetParameters(RHICmdList, NumVertexShaderInstructions, NumPixelShaderInstructions, View.GetFeatureLevel()); } else { // first Bind, then SetParameters() RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GetVertexDeclarationFVector4(), VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); PixelShader->SetParameters(RHICmdList, View, DecalData.MaterialProxy, *DecalData.DecalProxy, DecalData.FadeAlpha); } VertexShader->SetParameters(RHICmdList, View, FrustumComponentToClip); }
bool FBasePassOpaqueDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId, const bool bIsInstancedStereo ) { // Determine the mesh's material and blend mode. const FMaterial* Material = Mesh.MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()); const EBlendMode BlendMode = Material->GetBlendMode(); // Only draw opaque materials. if(!IsTranslucentBlendMode(BlendMode)) { ProcessBasePassMesh( RHICmdList, FProcessBasePassMeshParameters( Mesh, Material, PrimitiveSceneProxy, !bPreFog, DrawingContext.bEditorCompositeDepthTest, DrawingContext.TextureMode, View.GetFeatureLevel(), bIsInstancedStereo ), FDrawBasePassDynamicMeshAction( View, bBackFace, Mesh.DitheredLODTransitionAlpha, HitProxyId ) ); return true; } else { return false; } }
bool FBasePassForwardOpaqueDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { // Determine the mesh's material and blend mode. const auto FeatureLevel = View.GetFeatureLevel(); const auto ShaderPlatform = View.GetShaderPlatform(); const FMaterial* Material = Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel); const EBlendMode BlendMode = Material->GetBlendMode(); // Only draw opaque materials. if(!IsTranslucentBlendMode(BlendMode)) { ProcessBasePassMeshForForwardShading( RHICmdList, FProcessBasePassMeshParameters( Mesh, Material, PrimitiveSceneProxy, true, false, DrawingContext.TextureMode, FeatureLevel ), FDrawBasePassForwardShadingDynamicMeshAction( View, bBackFace, HitProxyId ) ); return true; } else { return false; } }
/** * Render a dynamic mesh using a translucent draw policy * @return true if the mesh rendered */ bool FTranslucencyForwardShadingDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { bool bDirty = false; // Determine the mesh's material and blend mode. const auto FeatureLevel = View.GetFeatureLevel(); const auto ShaderPlatform = View.GetShaderPlatform(); const FMaterial* Material = Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel); const EBlendMode BlendMode = Material->GetBlendMode(); // Only render translucent materials. if (IsTranslucentBlendMode(BlendMode)) { ProcessBasePassMeshForForwardShading( RHICmdList, FProcessBasePassMeshParameters( Mesh, Material, PrimitiveSceneProxy, true, false, ESceneRenderTargetsMode::SetTextures, FeatureLevel ), FDrawTranslucentMeshForwardShadingAction( View, bBackFace, HitProxyId ) ); bDirty = true; } return bDirty; }
/** Applies screen space radial blur passes. */ void ApplyRadialBlurPasses( FRHICommandListImmediate& RHICmdList, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo, /** First pass source - this will not be overwritten. */ TRefCountPtr<IPooledRenderTarget>& FirstPassSource, /** Subsequent pass source, will also contain the final result. */ TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, /** First pass dest. */ TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; const uint32 NumPasses = FMath::Max(GLightShaftBlurPasses, 0); for (uint32 PassIndex = 0; PassIndex < NumPasses; PassIndex++) { SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0.0f, FilterBufferSize.X, FilterBufferSize.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FBlurLightShaftsPixelShader> BlurLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BlurLightShaftsBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *BlurLightShaftsPixelShader); TRefCountPtr<IPooledRenderTarget>& EffectiveSource = PassIndex == 0 ? FirstPassSource : LightShaftsSource; /// ? BlurLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, PassIndex, EffectiveSource); { // Apply a radial blur to the bloom and occlusion mask DrawRectangle( RHICmdList, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, FilterBufferSize, FilterBufferSize, *ScreenVertexShader, EDRF_UseTriangleOptimization); } RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); // Swap input and output for the next pass Swap(LightShaftsSource, LightShaftsDest); } }
void FTranslucentPrimSet::DrawPrimitivesForForwardShading(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, FSceneRenderer& Renderer) const { // Draw sorted scene prims for (int32 PrimIdx = 0; PrimIdx < SortedPrims.Num(); PrimIdx++) { FPrimitiveSceneInfo* PrimitiveSceneInfo = SortedPrims[PrimIdx].PrimitiveSceneInfo; int32 PrimitiveId = PrimitiveSceneInfo->GetIndex(); const FPrimitiveViewRelevance& ViewRelevance = View.PrimitiveViewRelevanceMap[PrimitiveId]; checkSlow(ViewRelevance.HasTranslucency()); if(ViewRelevance.bDrawRelevance) { FTranslucencyForwardShadingDrawingPolicyFactory::ContextType Context; //@todo parallelrendering - come up with a better way to filter these by primitive for (int32 MeshBatchIndex = 0; MeshBatchIndex < View.DynamicMeshElements.Num(); MeshBatchIndex++) { const FMeshBatchAndRelevance& MeshBatchAndRelevance = View.DynamicMeshElements[MeshBatchIndex]; if (MeshBatchAndRelevance.PrimitiveSceneProxy == PrimitiveSceneInfo->Proxy) { const FMeshBatch& MeshBatch = *MeshBatchAndRelevance.Mesh; FTranslucencyForwardShadingDrawingPolicyFactory::DrawDynamicMesh(RHICmdList, View, Context, MeshBatch, false, false, MeshBatchAndRelevance.PrimitiveSceneProxy, MeshBatch.BatchHitProxyId); } } // Render static scene prim if( ViewRelevance.bStaticRelevance ) { // Render static meshes from static scene prim for( int32 StaticMeshIdx=0; StaticMeshIdx < PrimitiveSceneInfo->StaticMeshes.Num(); StaticMeshIdx++ ) { FStaticMesh& StaticMesh = PrimitiveSceneInfo->StaticMeshes[StaticMeshIdx]; if (View.StaticMeshVisibilityMap[StaticMesh.Id] // Only render static mesh elements using translucent materials && StaticMesh.IsTranslucent(View.GetFeatureLevel()) ) { FTranslucencyForwardShadingDrawingPolicyFactory::DrawStaticMesh( RHICmdList, View, FTranslucencyForwardShadingDrawingPolicyFactory::ContextType(), StaticMesh, false, PrimitiveSceneInfo->Proxy, StaticMesh.BatchHitProxyId ); } } } } } View.SimpleElementCollector.DrawBatchedElements(RHICmdList, View, FTexture2DRHIRef(), EBlendModeFilter::Translucent); }
/** Sets the bound shader state for either the per-pixel or per-sample fog pass. */ void SetFogShaders(FRHICommandList& RHICmdList, FScene* Scene, const FViewInfo& View, FLightShaftsOutput LightShaftsOutput) { if (Scene->ExponentialFogs.Num() > 0) { TShaderMapRef<FHeightFogVS> VertexShader(View.ShaderMap); TShaderMapRef<FExponentialHeightFogPS> ExponentialHeightFogPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), ExponentialBoundShaderState, GFogVertexDeclaration.VertexDeclarationRHI, *VertexShader, *ExponentialHeightFogPixelShader); VertexShader->SetParameters(RHICmdList, View); ExponentialHeightFogPixelShader->SetParameters(RHICmdList, View, LightShaftsOutput); } }
void FDecalRendering::SetShader(FRHICommandList& RHICmdList, const FViewInfo& View, const FTransientDecalRenderData& DecalData, const FMatrix& FrustumComponentToClip) { const FMaterialShaderMap* MaterialShaderMap = DecalData.MaterialResource->GetRenderingThreadShaderMap(); auto PixelShader = MaterialShaderMap->GetShader<FDeferredDecalPS>(); TShaderMapRef<FDeferredDecalVS> VertexShader(View.ShaderMap); const EDebugViewShaderMode DebugViewShaderMode = View.Family->GetDebugViewShaderMode(); if (DebugViewShaderMode != DVSM_None) { // For this to work, decal VS must output compatible interpolants. Currently this requires to use FDebugPSInLean. // Here we pass nullptr for the material interface because the use of a static bound shader state is only compatible with unique shaders. IDebugViewModePSInterface* DebugPixelShader = FDebugViewMode::GetPSInterface(View.ShaderMap, nullptr, DebugViewShaderMode); const uint32 NumPixelShaderInstructions = PixelShader->GetNumInstructions(); const uint32 NumVertexShaderInstructions = VertexShader->GetNumInstructions(); static FGlobalBoundShaderState BoundShaderState[DVSM_MAX]; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState[(uint32)DebugViewShaderMode], GetVertexDeclarationFVector4(), *VertexShader, DebugPixelShader->GetShader()); DebugPixelShader->SetParameters(RHICmdList, *VertexShader, PixelShader, DecalData.MaterialProxy, *DecalData.MaterialResource, View); DebugPixelShader->SetMesh(RHICmdList, View); } else { // first Bind, then SetParameters() RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GetVertexDeclarationFVector4(), VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); PixelShader->SetParameters(RHICmdList, View, DecalData.MaterialProxy, *DecalData.DecalProxy, DecalData.FadeAlpha); } // SetUniformBufferParameter() need to happen after the shader has been set otherwise a DebugBreak could occur. // we don't have the Primitive uniform buffer setup for decals (later we want to batch) { auto& PrimitiveVS = VertexShader->GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(); auto& PrimitivePS = PixelShader->GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(); // uncomment to track down usage of the Primitive uniform buffer // check(!PrimitiveVS.IsBound()); // check(!PrimitivePS.IsBound()); // to prevent potential shader error (UE-18852 ElementalDemo crashes due to nil constant buffer) SetUniformBufferParameter(RHICmdList, VertexShader->GetVertexShader(), PrimitiveVS, GIdentityPrimitiveUniformBuffer); if (DebugViewShaderMode == DVSM_None) { SetUniformBufferParameter(RHICmdList, PixelShader->GetPixelShader(), PrimitivePS, GIdentityPrimitiveUniformBuffer); } } VertexShader->SetParameters(RHICmdList, View, FrustumComponentToClip); }
void PrefilterPlanarReflection(FRHICommandListImmediate& RHICmdList, FViewInfo& View, const FPlanarReflectionSceneProxy* ReflectionSceneProxy, const FRenderTarget* Target) { FTextureRHIParamRef SceneColorInput = FSceneRenderTargets::Get(RHICmdList).GetSceneColorTexture(); if(View.FeatureLevel >= ERHIFeatureLevel::SM4) { // Note: null velocity buffer, so dynamic object temporal AA will not be correct TRefCountPtr<IPooledRenderTarget> VelocityRT; TRefCountPtr<IPooledRenderTarget> FilteredSceneColor; GPostProcessing.ProcessPlanarReflection(RHICmdList, View, VelocityRT, FilteredSceneColor); if (FilteredSceneColor) { SceneColorInput = FilteredSceneColor->GetRenderTargetItem().ShaderResourceTexture; } } { SCOPED_DRAW_EVENT(RHICmdList, PrefilterPlanarReflection); FRHIRenderTargetView ColorView(Target->GetRenderTargetTexture(), 0, -1, ERenderTargetLoadAction::ENoAction, ERenderTargetStoreAction::EStore); FRHISetRenderTargetsInfo Info(1, &ColorView, FRHIDepthRenderTargetView()); RHICmdList.SetRenderTargetsAndClear(Info); RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<TDeferredLightVS<false> > VertexShader(View.ShaderMap); TShaderMapRef<FPrefilterPlanarReflectionPS<bEnablePlanarReflectionPrefilter> > PixelShader(View.ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, View, ReflectionSceneProxy, SceneColorInput); VertexShader->SetSimpleLightParameters(RHICmdList, View, FSphere(0)); DrawRectangle( RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Size(), FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(), *VertexShader, EDRF_UseTriangleOptimization); } }
void FLightPropagationVolume::Visualise(FRHICommandList& RHICmdList, const FViewInfo& View) const { SCOPED_DRAW_EVENT(RHICmdList, LpvVisualise); check(View.GetFeatureLevel() == ERHIFeatureLevel::SM5); TShaderMapRef<FLpvVisualiseVS> VertexShader(View.ShaderMap); TShaderMapRef<FLpvVisualiseGS> GeometryShader(View.ShaderMap); TShaderMapRef<FLpvVisualisePS> PixelShader(View.ShaderMap); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI()); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), LpvVisBoundShaderState, GSimpleElementVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader, *GeometryShader); VertexShader->SetParameters(RHICmdList, View); GeometryShader->SetParameters(RHICmdList, View); PixelShader->SetParameters(RHICmdList, this, View); RHICmdList.SetStreamSource(0, NULL, 0, 0); RHICmdList.DrawPrimitive(PT_PointList, 0, 1, 32 * 3); PixelShader->UnbindBuffers(RHICmdList); }
bool ShouldRenderScreenSpaceAmbientOcclusion(const FViewInfo& View) { bool bEnabled = true; if (!IsLpvIndirectPassRequired(View)) { bEnabled = View.FinalPostProcessSettings.AmbientOcclusionIntensity > 0 && View.Family->EngineShowFlags.Lighting && View.FinalPostProcessSettings.AmbientOcclusionRadius >= 0.1f && !View.Family->UseDebugViewPS() && (FSSAOHelper::IsBasePassAmbientOcclusionRequired(View) || IsAmbientCubemapPassRequired(View) || IsReflectionEnvironmentActive(View) || IsSkylightActive(View) || View.Family->EngineShowFlags.VisualizeBuffer) && !IsAnyForwardShadingEnabled(View.GetShaderPlatform()); } return bEnabled; }
bool IsMotionBlurEnabled(const FViewInfo& View) { if (!(View.GetFeatureLevel() >= ERHIFeatureLevel::SM4)) { return false; } int32 MotionBlurQuality = GetMotionBlurQualityFromCVar(); return View.Family->EngineShowFlags.PostProcessing && View.Family->EngineShowFlags.MotionBlur && View.FinalPostProcessSettings.MotionBlurAmount > 0.001f && View.FinalPostProcessSettings.MotionBlurMax > 0.001f && View.Family->bRealtimeUpdate && MotionBlurQuality > 0 && !View.bIsSceneCapture && !(View.Family->Views.Num() > 1); }
bool FVelocityDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { // Only draw opaque materials in the depth pass. const auto FeatureLevel = View.GetFeatureLevel(); const FMaterialRenderProxy* MaterialRenderProxy = Mesh.MaterialRenderProxy; const FMaterial* Material = MaterialRenderProxy->GetMaterial(FeatureLevel); EBlendMode BlendMode = Material->GetBlendMode(); if(BlendMode == BLEND_Opaque || BlendMode == BLEND_Masked) { // This should be enforced at a higher level //@todo - figure out why this is failing and re-enable //check(FVelocityDrawingPolicy::HasVelocity(View, PrimitiveSceneInfo)); if (!Material->IsMasked() && !Material->IsTwoSided() && !Material->MaterialModifiesMeshPosition_RenderThread()) { // Default material doesn't handle masked, and doesn't have the correct bIsTwoSided setting. MaterialRenderProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(false); } FVelocityDrawingPolicy DrawingPolicy(Mesh.VertexFactory, MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(FeatureLevel), FeatureLevel); if(DrawingPolicy.SupportsVelocity()) { RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, FVelocityDrawingPolicy::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); ++BatchElementIndex) { DrawingPolicy.SetMeshRenderState(RHICmdList, View, PrimitiveSceneProxy, Mesh, BatchElementIndex, bBackFace, FMeshDrawingPolicy::ElementDataType(), FVelocityDrawingPolicy::ContextDataType()); DrawingPolicy.DrawMesh(RHICmdList, Mesh, BatchElementIndex); } return true; } } return false; }
void FDecalRendering::SetShader(FRHICommandList& RHICmdList, const FViewInfo& View, bool bShaderComplexity, const FTransientDecalRenderData& DecalData, const FMatrix& FrustumComponentToClip) { const FMaterialShaderMap* MaterialShaderMap = DecalData.MaterialResource->GetRenderingThreadShaderMap(); auto PixelShader = MaterialShaderMap->GetShader<FDeferredDecalPS>(); TShaderMapRef<FDeferredDecalVS> VertexShader(View.ShaderMap); // we don't have the Primitive uniform buffer setup for decals (later we want to batch) { auto& PrimitiveVS = VertexShader->GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(); auto& PrimitivePS = PixelShader->GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(); // uncomment to track down usage of the Primitive uniform buffer // check(!PrimitiveVS.IsBound()); // check(!PrimitivePS.IsBound()); // to prevent potential shader error (UE-18852 ElementalDemo crashes due to nil constant buffer) SetUniformBufferParameter(RHICmdList, VertexShader->GetVertexShader(), PrimitiveVS, GIdentityPrimitiveUniformBuffer); SetUniformBufferParameter(RHICmdList, PixelShader->GetPixelShader(), PrimitivePS, GIdentityPrimitiveUniformBuffer); } if(bShaderComplexity) { TShaderMapRef<FShaderComplexityAccumulatePS> VisualizePixelShader(View.ShaderMap); const uint32 NumPixelShaderInstructions = PixelShader->GetNumInstructions(); const uint32 NumVertexShaderInstructions = VertexShader->GetNumInstructions(); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GetVertexDeclarationFVector4(), *VertexShader, *VisualizePixelShader); VisualizePixelShader->SetParameters(RHICmdList, NumVertexShaderInstructions, NumPixelShaderInstructions, View.GetFeatureLevel()); } else { // first Bind, then SetParameters() RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GetVertexDeclarationFVector4(), VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); PixelShader->SetParameters(RHICmdList, View, DecalData.MaterialProxy, *DecalData.DecalProxy, DecalData.FadeAlpha); } VertexShader->SetParameters(RHICmdList, View, FrustumComponentToClip); }
void FinishOcclusionTerm(FRHICommandList& RHICmdList, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo, TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0.0f, FilterBufferSize.X, FilterBufferSize.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FFinishOcclusionPixelShader> MaskOcclusionTermPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), AccumulateTermBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *MaskOcclusionTermPixelShader); /// ? MaskOcclusionTermPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, LightShaftsSource); { // Apply a radial blur to the bloom and occlusion mask DrawRectangle( RHICmdList, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, FilterBufferSize, FilterBufferSize, *ScreenVertexShader, EDRF_UseTriangleOptimization); } RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); }
void ApplyLightShaftBloom(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo, TRefCountPtr<IPooledRenderTarget>& LightShaftsSource) { FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); SceneContext.BeginRenderingSceneColor(RHICmdList, ESimpleRenderTargetMode::EUninitializedColorExistingDepth, FExclusiveDepthStencil::DepthRead_StencilWrite); RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); TShaderMapRef<FApplyLightShaftsPixelShader> ApplyLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), ApplyLightShaftsBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *ApplyLightShaftsPixelShader); /// ? ApplyLightShaftsPixelShader->SetParameters(RHICmdList, View, LightShaftsSource); const FIntPoint BufferSize = SceneContext.GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = SceneContext.GetBufferSizeXY() / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; DrawRectangle( RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, FIntPoint(View.ViewRect.Width(), View.ViewRect.Height()), FilterBufferSize, *ScreenVertexShader, EDRF_UseTriangleOptimization); SceneContext.FinishRenderingSceneColor(RHICmdList, false); }
bool FDepthDrawingPolicyFactory::DrawMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, const uint64& BatchElementMask, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { bool bDirty = false; //Do a per-FMeshBatch check on top of the proxy check in RenderPrePass to handle the case where a proxy that is relevant //to the depth only pass has to submit multiple FMeshElements but only some of them should be used as occluders. if (Mesh.bUseAsOccluder || DrawingContext.DepthDrawingMode == DDM_AllOpaque) { const FMaterialRenderProxy* MaterialRenderProxy = Mesh.MaterialRenderProxy; const FMaterial* Material = MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()); const EBlendMode BlendMode = Material->GetBlendMode(); // Check to see if the primitive is currently fading in or out using the screen door effect. If it is, // then we can't assume the object is opaque as it may be forcibly masked. const FSceneViewState* SceneViewState = static_cast<const FSceneViewState*>( View.State ); if ( BlendMode == BLEND_Opaque && Mesh.VertexFactory->SupportsPositionOnlyStream() && !Material->MaterialModifiesMeshPosition_RenderThread()) { //render opaque primitives that support a separate position-only vertex buffer const FMaterialRenderProxy* DefaultProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(false); FPositionOnlyDepthDrawingPolicy DrawingPolicy(Mesh.VertexFactory, DefaultProxy, *DefaultProxy->GetMaterial(View.GetFeatureLevel()), Material->IsTwoSided(), Material->IsWireframe()); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(View.GetFeatureLevel())); DrawingPolicy.SetSharedState(RHICmdList, &View, FDepthDrawingPolicy::ContextDataType()); int32 BatchElementIndex = 0; uint64 Mask = BatchElementMask; do { if(Mask & 1) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,FPositionOnlyDepthDrawingPolicy::ElementDataType(),FDepthDrawingPolicy::ContextDataType()); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } Mask >>= 1; BatchElementIndex++; } while(Mask); bDirty = true; } else if (!IsTranslucentBlendMode(BlendMode)) { const bool bMaterialMasked = Material->IsMasked(); bool bDraw = true; switch(DrawingContext.DepthDrawingMode) { case DDM_AllOpaque: break; case DDM_AllOccluders: break; case DDM_NonMaskedOnly: bDraw = !bMaterialMasked; break; default: check(!"Unrecognized DepthDrawingMode"); } if(bDraw) { if (!bMaterialMasked && !Material->MaterialModifiesMeshPosition_RenderThread()) { // Override with the default material for opaque materials that are not two sided MaterialRenderProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(false); } FDepthDrawingPolicy DrawingPolicy(Mesh.VertexFactory, MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()), Material->IsTwoSided(), View.GetFeatureLevel()); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(View.GetFeatureLevel())); DrawingPolicy.SetSharedState(RHICmdList, &View, FDepthDrawingPolicy::ContextDataType()); int32 BatchElementIndex = 0; uint64 Mask = BatchElementMask; do { if(Mask & 1) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,FMeshDrawingPolicy::ElementDataType(),FDepthDrawingPolicy::ContextDataType()); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } Mask >>= 1; BatchElementIndex++; } while(Mask); bDirty = true; } } }
void DownsamplePass(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, const FLightSceneInfo* LightSceneInfo, TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(DownSampledXY.X, DownSampledXY.Y, 0.0f, DownSampledXY.X + DownsampledSizeX, DownSampledXY.Y + DownsampledSizeY, 1.0f); // Set shaders and texture TShaderMapRef<FDownsampleLightShaftsVertexShader> DownsampleLightShaftsVertexShader(View.ShaderMap); TRefCountPtr<IPooledRenderTarget> UnusedRT; switch(LightSceneInfo->Proxy->GetLightType()) { case LightType_Directional: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Directional, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsampleDirectionalLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; case LightType_Spot: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Spot, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsampleSpotLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; default: case LightType_Point: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Point, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsamplePointLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; } DownsampleLightShaftsVertexShader->SetParameters(RHICmdList, View); // No depth tests, no backface culling. RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); // Downsample scene color and depth, and convert them into a bloom term and an occlusion masking term DrawRectangle( RHICmdList, 0, 0, DownsampledSizeX, DownsampledSizeY, View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(DownsampledSizeX, DownsampledSizeY), BufferSize, *DownsampleLightShaftsVertexShader, EDRF_UseTriangleOptimization); RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); Swap(LightShaftsSource, LightShaftsDest); }
void FCompositionLighting::ProcessAfterLighting(FRHICommandListImmediate& RHICmdList, FViewInfo& View) { check(IsInRenderingThread()); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDiffuse); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapNormal); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDepth); { FMemMark Mark(FMemStack::Get()); FRenderingCompositePassContext CompositeContext(RHICmdList, View); FPostprocessContext Context(CompositeContext.Graph, View); FRenderingCompositeOutputRef AmbientOcclusion; // Screen Space Subsurface Scattering { float Radius = CVarSSSScale.GetValueOnRenderThread(); bool bSimpleDynamicLighting = IsSimpleDynamicLightingEnabled(); bool bScreenSpaceSubsurfacePassNeeded = (View.ShadingModelMaskInView & (1 << MSM_SubsurfaceProfile)) != 0; if (bScreenSpaceSubsurfacePassNeeded && Radius > 0 && !bSimpleDynamicLighting && View.Family->EngineShowFlags.SubsurfaceScattering && //@todo-rco: Remove this when we fix the cross-compiler !IsOpenGLPlatform(View.GetShaderPlatform())) { // can be optimized out if we don't do split screen/stereo rendering (should be done after we some post process refactoring) FRenderingCompositePass* PassExtractSpecular = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceExtractSpecular()); PassExtractSpecular->SetInput(ePId_Input0, Context.FinalOutput); FRenderingCompositePass* PassSetup = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceSetup(View)); PassSetup->SetInput(ePId_Input0, Context.FinalOutput); FRenderingCompositePass* Pass0 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(0)); Pass0->SetInput(ePId_Input0, PassSetup); FRenderingCompositePass* Pass1 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(1)); Pass1->SetInput(ePId_Input0, Pass0); Pass1->SetInput(ePId_Input1, PassSetup); // full res composite pass, no blurring (Radius=0) FRenderingCompositePass* RecombinePass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceRecombine()); RecombinePass->SetInput(ePId_Input0, Pass1); RecombinePass->SetInput(ePId_Input1, PassExtractSpecular); SCOPED_DRAW_EVENT(RHICmdList, CompositionLighting_SSSSS); CompositeContext.Process(RecombinePass, TEXT("CompositionLighting_SSSSS")); } } // The graph setup should be finished before this line ---------------------------------------- SCOPED_DRAW_EVENT(RHICmdList, CompositionAfterLighting); // we don't replace the final element with the scenecolor because this is what those passes should do by themself CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting")); } // We only release the after the last view was processed (SplitScreen) if(View.Family->Views[View.Family->Views.Num() - 1] == &View) { // The RT should be released as early as possible to allow sharing of that memory for other purposes. // This becomes even more important with some limited VRam (XBoxOne). SceneContext.SetLightAttenuation(0); } }
void FCompositionLighting::ProcessAfterLighting(FRHICommandListImmediate& RHICmdList, FViewInfo& View) { check(IsInRenderingThread()); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); { FMemMark Mark(FMemStack::Get()); FRenderingCompositePassContext CompositeContext(RHICmdList, View); FPostprocessContext Context(RHICmdList, CompositeContext.Graph, View); FRenderingCompositeOutputRef AmbientOcclusion; // Screen Space Subsurface Scattering { float Radius = CVarSSSScale.GetValueOnRenderThread(); bool bSimpleDynamicLighting = IsAnyForwardShadingEnabled(View.GetShaderPlatform()); bool bScreenSpaceSubsurfacePassNeeded = ((View.ShadingModelMaskInView & (1 << MSM_SubsurfaceProfile)) != 0) && IsSubsurfacePostprocessRequired(); bool bSubsurfaceAllowed = CVarSubsurfaceScattering.GetValueOnRenderThread() == 1; if (bScreenSpaceSubsurfacePassNeeded && !bSimpleDynamicLighting && bSubsurfaceAllowed) { bool bHalfRes = CVarSSSHalfRes.GetValueOnRenderThread() != 0; bool bSingleViewportMode = View.Family->Views.Num() == 1; if(Radius > 0 && View.Family->EngineShowFlags.SubsurfaceScattering) { FRenderingCompositePass* PassSetup = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceSetup(View, bHalfRes)); PassSetup->SetInput(ePId_Input0, Context.FinalOutput); FRenderingCompositePass* PassX = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(0, bHalfRes)); PassX->SetInput(ePId_Input0, PassSetup); FRenderingCompositePass* PassY = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(1, bHalfRes)); PassY->SetInput(ePId_Input0, PassX); PassY->SetInput(ePId_Input1, PassSetup); // full res composite pass, no blurring (Radius=0), replaces SceneColor FRenderingCompositePass* RecombinePass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceRecombine(bHalfRes, bSingleViewportMode)); RecombinePass->SetInput(ePId_Input0, Context.FinalOutput); RecombinePass->SetInput(ePId_Input1, PassY); RecombinePass->SetInput(ePId_Input2, PassSetup); Context.FinalOutput = FRenderingCompositeOutputRef(RecombinePass); } else { // needed for Scalability FRenderingCompositePass* RecombinePass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceRecombine(bHalfRes, bSingleViewportMode)); RecombinePass->SetInput(ePId_Input0, Context.FinalOutput); Context.FinalOutput = FRenderingCompositeOutputRef(RecombinePass); } } } // The graph setup should be finished before this line ---------------------------------------- SCOPED_DRAW_EVENT(RHICmdList, CompositionAfterLighting); SCOPED_GPU_STAT(RHICmdList, Stat_GPU_CompositionPostLighting); // we don't replace the final element with the scenecolor because this is what those passes should do by themself CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting")); } // We only release the after the last view was processed (SplitScreen) if(View.Family->Views[View.Family->Views.Num() - 1] == &View) { // The RT should be released as early as possible to allow sharing of that memory for other purposes. // This becomes even more important with some limited VRam (XBoxOne). SceneContext.SetLightAttenuation(0); } }
void FDecalRendering::BuildVisibleDecalList(const FScene& Scene, const FViewInfo& View, EDecalRenderStage DecalRenderStage, FTransientDecalRenderDataList& OutVisibleDecals) { QUICK_SCOPE_CYCLE_COUNTER(BuildVisibleDecalList); OutVisibleDecals.Empty(Scene.Decals.Num()); const float FadeMultiplier = CVarDecalFadeScreenSizeMultiplier.GetValueOnRenderThread(); const EShaderPlatform ShaderPlatform = View.GetShaderPlatform(); const bool bIsPerspectiveProjection = View.IsPerspectiveProjection(); // Build a list of decals that need to be rendered for this view in SortedDecals for (const FDeferredDecalProxy* DecalProxy : Scene.Decals) { bool bIsShown = true; if (!DecalProxy->IsShown(&View)) { bIsShown = false; } const FMatrix ComponentToWorldMatrix = DecalProxy->ComponentTrans.ToMatrixWithScale(); // can be optimized as we test against a sphere around the box instead of the box itself const float ConservativeRadius = FMath::Sqrt( ComponentToWorldMatrix.GetScaledAxis(EAxis::X).SizeSquared() + ComponentToWorldMatrix.GetScaledAxis(EAxis::Y).SizeSquared() + ComponentToWorldMatrix.GetScaledAxis(EAxis::Z).SizeSquared()); // can be optimized as the test is too conservative (sphere instead of OBB) if(ConservativeRadius < SMALL_NUMBER || !View.ViewFrustum.IntersectSphere(ComponentToWorldMatrix.GetOrigin(), ConservativeRadius)) { bIsShown = false; } if (bIsShown) { FTransientDecalRenderData Data(Scene, DecalProxy, ConservativeRadius); // filter out decals with blend modes that are not supported on current platform if (IsBlendModeSupported(ShaderPlatform, Data.DecalBlendMode)) { if (bIsPerspectiveProjection && Data.DecalProxy->Component->FadeScreenSize != 0.0f) { float Distance = (View.ViewMatrices.ViewOrigin - ComponentToWorldMatrix.GetOrigin()).Size(); float Radius = ComponentToWorldMatrix.GetMaximumAxisScale(); float CurrentScreenSize = ((Radius / Distance) * FadeMultiplier); // fading coefficient needs to increase with increasing field of view and decrease with increasing resolution // FadeCoeffScale is an empirically determined constant to bring us back roughly to fraction of screen size for FadeScreenSize const float FadeCoeffScale = 600.0f; float FOVFactor = ((2.0f/View.ViewMatrices.ProjMatrix.M[0][0]) / View.ViewRect.Width()) * FadeCoeffScale; float FadeCoeff = Data.DecalProxy->Component->FadeScreenSize * FOVFactor; float FadeRange = FadeCoeff * 0.5f; float Alpha = (CurrentScreenSize - FadeCoeff) / FadeRange; Data.FadeAlpha = FMath::Min(Alpha, 1.0f); } EDecalRenderStage LocalDecalRenderStage = FDecalRenderingCommon::ComputeRenderStage(ShaderPlatform, Data.DecalBlendMode); // we could do this test earlier to avoid the decal intersection but getting DecalBlendMode also costs if (View.Family->EngineShowFlags.ShaderComplexity || (DecalRenderStage == LocalDecalRenderStage && Data.FadeAlpha>0.0f) ) { OutVisibleDecals.Add(Data); } } } } if (OutVisibleDecals.Num() > 0) { // Sort by sort order to allow control over composited result // Then sort decals by state to reduce render target switches // Also sort by component since Sort() is not stable struct FCompareFTransientDecalRenderData { FORCEINLINE bool operator()(const FTransientDecalRenderData& A, const FTransientDecalRenderData& B) const { if (B.DecalProxy->SortOrder != A.DecalProxy->SortOrder) { return A.DecalProxy->SortOrder < B.DecalProxy->SortOrder; } // bHasNormal here is more important then blend mode because we want to render every decals that output normals before those that read normal. if (B.bHasNormal != A.bHasNormal) { return B.bHasNormal < A.bHasNormal; // < so that those outputting normal are first. } if (B.DecalBlendMode != A.DecalBlendMode) { return (int32)B.DecalBlendMode < (int32)A.DecalBlendMode; } // Batch decals with the same material together if (B.MaterialProxy != A.MaterialProxy) { return B.MaterialProxy < A.MaterialProxy; } return (PTRINT)B.DecalProxy->Component < (PTRINT)A.DecalProxy->Component; } }; // Sort decals by blend mode to reduce render target switches OutVisibleDecals.Sort(FCompareFTransientDecalRenderData()); } }
bool IsLpvIndirectPassRequired(const FViewInfo& View) { FScene* Scene = (FScene*)View.Family->Scene; const FSceneViewState* ViewState = (FSceneViewState*)View.State; if(ViewState) { // This check should be inclusive to stereo views const bool bIncludeStereoViews = true; FLightPropagationVolume* LightPropagationVolume = ViewState->GetLightPropagationVolume(View.GetFeatureLevel(), bIncludeStereoViews); if(LightPropagationVolume) { const FLightPropagationVolumeSettings& LPVSettings = View.FinalPostProcessSettings.BlendableManager.GetSingleFinalDataConst<FLightPropagationVolumeSettings>(); if(LPVSettings.LPVIntensity > 0.0f) { return true; } } } return false; }
bool FLightMapDensityDrawingPolicyFactory::DrawDynamicMesh( FRHICommandList& RHICmdList, const FViewInfo& View, ContextType DrawingContext, const FMeshBatch& Mesh, bool bBackFace, bool bPreFog, const FPrimitiveSceneProxy* PrimitiveSceneProxy, FHitProxyId HitProxyId ) { bool bDirty = false; const auto FeatureLevel = View.GetFeatureLevel(); const FMaterialRenderProxy* MaterialRenderProxy = Mesh.MaterialRenderProxy; const FMaterial* Material = MaterialRenderProxy->GetMaterial(FeatureLevel); const EBlendMode BlendMode = Material->GetBlendMode(); const FMeshDrawingRenderState DrawRenderState(Mesh.DitheredLODTransitionAlpha); const bool bMaterialMasked = Material->IsMasked(); const bool bMaterialModifiesMesh = Material->MaterialModifiesMeshPosition_RenderThread(); if (!bMaterialMasked && !bMaterialModifiesMesh) { // Override with the default material for opaque materials that are not two sided MaterialRenderProxy = GEngine->LevelColorationLitMaterial->GetRenderProxy(false); } bool bIsLitMaterial = (Material->GetShadingModel() != MSM_Unlit); /*const */FLightMapInteraction LightMapInteraction = (Mesh.LCI && bIsLitMaterial) ? Mesh.LCI->GetLightMapInteraction(FeatureLevel) : FLightMapInteraction(); // force simple lightmaps based on system settings bool bAllowHighQualityLightMaps = AllowHighQualityLightmaps(FeatureLevel) && LightMapInteraction.AllowsHighQualityLightmaps(); if (bIsLitMaterial && PrimitiveSceneProxy && (LightMapInteraction.GetType() == LMIT_Texture)) { // Should this object be texture lightmapped? Ie, is lighting not built for it?? bool bUseDummyLightMapPolicy = Mesh.LCI == NULL || Mesh.LCI->GetLightMapInteraction(FeatureLevel).GetType() != LMIT_Texture; if (!bUseDummyLightMapPolicy) { if (bAllowHighQualityLightMaps) { TLightMapDensityDrawingPolicy< TUniformLightMapPolicy<LMP_HQ_LIGHTMAP> > DrawingPolicy(View, Mesh.VertexFactory, MaterialRenderProxy, TUniformLightMapPolicy<LMP_HQ_LIGHTMAP>(), BlendMode); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, TLightMapDensityDrawingPolicy< FUniformLightMapPolicy >::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,DrawRenderState, Mesh.LCI, TLightMapDensityDrawingPolicy<FUniformLightMapPolicy>::ContextDataType() ); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } bDirty = true; } else { TLightMapDensityDrawingPolicy< TUniformLightMapPolicy<LMP_LQ_LIGHTMAP> > DrawingPolicy(View, Mesh.VertexFactory, MaterialRenderProxy, TUniformLightMapPolicy<LMP_LQ_LIGHTMAP>(), BlendMode); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, TLightMapDensityDrawingPolicy< FUniformLightMapPolicy >::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,DrawRenderState, Mesh.LCI, TLightMapDensityDrawingPolicy<FUniformLightMapPolicy>::ContextDataType() ); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } bDirty = true; } } else { TLightMapDensityDrawingPolicy<TUniformLightMapPolicy<LMP_DUMMY> > DrawingPolicy(View, Mesh.VertexFactory, MaterialRenderProxy, TUniformLightMapPolicy<LMP_DUMMY>(), BlendMode); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, TLightMapDensityDrawingPolicy<FUniformLightMapPolicy >::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,DrawRenderState, Mesh.LCI, TLightMapDensityDrawingPolicy<FUniformLightMapPolicy>::ContextDataType() ); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } bDirty = true; } } else { TLightMapDensityDrawingPolicy<TUniformLightMapPolicy<LMP_NO_LIGHTMAP> > DrawingPolicy(View, Mesh.VertexFactory, MaterialRenderProxy, TUniformLightMapPolicy<LMP_NO_LIGHTMAP>(), BlendMode); RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, TLightMapDensityDrawingPolicy<TUniformLightMapPolicy<LMP_NO_LIGHTMAP> >::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++) { DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,bBackFace,DrawRenderState, Mesh.LCI, TLightMapDensityDrawingPolicy<FUniformLightMapPolicy>::ContextDataType() ); DrawingPolicy.DrawMesh(RHICmdList, Mesh,BatchElementIndex); } bDirty = true; } return bDirty; }
void SetParameters(FRHICommandList& RHICmdList, const FMaterialRenderProxy* MaterialRenderProxy,const FViewInfo& View) { FMeshMaterialShader::SetParameters(RHICmdList, (FDomainShaderRHIParamRef)GetDomainShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()), View, ESceneRenderTargetsMode::DontSet); }
void SetParameters(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FMaterialRenderProxy* MaterialRenderProxy,const FViewInfo& View) { FMeshMaterialShader::SetParameters(RHICmdList, GetVertexShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View.GetFeatureLevel()), View, ESceneRenderTargetsMode::DontSet); }