/** * 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; }
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); }
/** 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; } }
/** * 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; }
/** 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 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 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; }
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); }
int32 FUniformMeshConverter::Convert( FRHICommandListImmediate& RHICmdList, FSceneRenderer& Renderer, FViewInfo& View, const FPrimitiveSceneInfo* PrimitiveSceneInfo, int32 LODIndex, FUniformMeshBuffers*& OutUniformMeshBuffers, const FMaterialRenderProxy*& OutMaterialRenderProxy, FUniformBufferRHIParamRef& OutPrimitiveUniformBuffer) { const FPrimitiveSceneProxy* PrimitiveSceneProxy = PrimitiveSceneInfo->Proxy; const auto FeatureLevel = View.GetFeatureLevel(); TArray<FMeshBatch> MeshElements; PrimitiveSceneInfo->Proxy->GetMeshDescription(LODIndex, MeshElements); int32 NumTriangles = 0; for (int32 MeshIndex = 0; MeshIndex < MeshElements.Num(); MeshIndex++) { if (ShouldConvertMesh(MeshElements[MeshIndex])) { NumTriangles += MeshElements[MeshIndex].GetNumPrimitives(); } } if (NumTriangles > 0) { if (GUniformMeshTemporaryBuffers.MaxElements < NumTriangles * 3) { GUniformMeshTemporaryBuffers.MaxElements = NumTriangles * 3; GUniformMeshTemporaryBuffers.Release(); GUniformMeshTemporaryBuffers.Initialize(); } RHICmdList.SetRenderTargets(0, (const FRHIRenderTargetView*)NULL, NULL, 0, (const FUnorderedAccessViewRHIParamRef*)NULL); uint32 Offsets[1] = {0}; const FVertexBufferRHIParamRef StreamOutTargets[1] = {GUniformMeshTemporaryBuffers.TriangleData.GetReference()}; RHICmdList.SetStreamOutTargets(1, StreamOutTargets, Offsets); for (int32 MeshIndex = 0; MeshIndex < MeshElements.Num(); MeshIndex++) { const FMeshBatch& Mesh = MeshElements[MeshIndex]; if (ShouldConvertMesh(Mesh)) { FConvertToUniformMeshDrawingPolicy DrawingPolicy( Mesh.VertexFactory, Mesh.MaterialRenderProxy, *Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel), FeatureLevel); //@todo - fix OutMaterialRenderProxy = Mesh.MaterialRenderProxy; RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel)); DrawingPolicy.SetSharedState(RHICmdList, &View, FConvertToUniformMeshDrawingPolicy::ContextDataType()); for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++) { //@todo - fix OutPrimitiveUniformBuffer = IsValidRef(Mesh.Elements[BatchElementIndex].PrimitiveUniformBuffer) ? Mesh.Elements[BatchElementIndex].PrimitiveUniformBuffer : *Mesh.Elements[BatchElementIndex].PrimitiveUniformBufferResource; DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,false,FMeshDrawingRenderState(),FConvertToUniformMeshDrawingPolicy::ElementDataType(), FConvertToUniformMeshDrawingPolicy::ContextDataType()); DrawingPolicy.DrawMesh(RHICmdList, Mesh, BatchElementIndex); } } } RHICmdList.SetStreamOutTargets(1, (const FVertexBufferRHIParamRef*)NULL, Offsets); } OutUniformMeshBuffers = &GUniformMeshTemporaryBuffers; return NumTriangles; }
void BuildHZB( FRHICommandListImmediate& RHICmdList, FViewInfo& View ) { QUICK_SCOPE_CYCLE_COUNTER(STAT_BuildHZB); // View.ViewRect.{Width,Height}() are most likely to be < 2^24, so the float // conversion won't loss any precision (assuming float have 23bits for mantissa) const int32 NumMipsX = FMath::Max(FPlatformMath::CeilToInt(FMath::Log2(float(View.ViewRect.Width()))) - 1, 1); const int32 NumMipsY = FMath::Max(FPlatformMath::CeilToInt(FMath::Log2(float(View.ViewRect.Height()))) - 1, 1); const uint32 NumMips = FMath::Max(NumMipsX, NumMipsY); // Must be power of 2 const FIntPoint HZBSize( 1 << NumMipsX, 1 << NumMipsY ); View.HZBMipmap0Size = HZBSize; FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(HZBSize, PF_R16F, FClearValueBinding::None, TexCreate_None, TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_NoFastClear, false, NumMips)); Desc.Flags |= TexCreate_FastVRAM; GRenderTargetPool.FindFreeElement(RHICmdList, Desc, View.HZB, TEXT("HZB") ); FSceneRenderTargetItem& HZBRenderTarget = View.HZB->GetRenderTargetItem(); FTextureRHIParamRef HZBRenderTargetRef = HZBRenderTarget.TargetableTexture.GetReference(); // Mip 0 { SCOPED_DRAW_EVENTF(RHICmdList, BuildHZB, TEXT("HZB SetupMip 0 %dx%d"), HZBSize.X, HZBSize.Y); SetRenderTarget(RHICmdList, HZBRenderTarget.TargetableTexture, 0, NULL); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState< false, CF_Always >::GetRHI()); TShaderMapRef< FPostProcessVS > VertexShader(View.ShaderMap); TShaderMapRef< THZBBuildPS<0> > PixelShader(View.ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); // Imperfect sampling, doesn't matter too much PixelShader->SetParameters( RHICmdList, View ); RHICmdList.SetViewport(0, 0, 0.0f, HZBSize.X, HZBSize.Y, 1.0f); DrawRectangle( RHICmdList, 0, 0, HZBSize.X, HZBSize.Y, View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), HZBSize, FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(), *VertexShader, EDRF_UseTriangleOptimization); //Use RWBarrier since we don't transition individual subresources. Basically treat the whole texture as R/W as we walk down the mip chain. RHICmdList.TransitionResources(EResourceTransitionAccess::ERWSubResBarrier, &HZBRenderTargetRef, 1); } FIntPoint SrcSize = HZBSize; FIntPoint DstSize = SrcSize / 2; SCOPED_DRAW_EVENTF(RHICmdList, BuildHZB, TEXT("HZB SetupMips 1..%d %dx%d Mips:%d"), NumMips - 1, DstSize.X, DstSize.Y); // Downsampling... for( uint8 MipIndex = 1; MipIndex < NumMips; MipIndex++ ) { DstSize.X = FMath::Max(DstSize.X, 1); DstSize.Y = FMath::Max(DstSize.Y, 1); SetRenderTarget(RHICmdList, HZBRenderTarget.TargetableTexture, MipIndex, NULL); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState< false, CF_Always >::GetRHI()); TShaderMapRef< FPostProcessVS > VertexShader(View.ShaderMap); TShaderMapRef< THZBBuildPS<1> > PixelShader(View.ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, View, SrcSize, HZBRenderTarget.MipSRVs[ MipIndex - 1 ] ); RHICmdList.SetViewport(0, 0, 0.0f, DstSize.X, DstSize.Y, 1.0f); DrawRectangle( RHICmdList, 0, 0, DstSize.X, DstSize.Y, 0, 0, SrcSize.X, SrcSize.Y, DstSize, SrcSize, *VertexShader, EDRF_UseTriangleOptimization); SrcSize /= 2; DstSize /= 2; //Use ERWSubResBarrier since we don't transition individual subresources. Basically treat the whole texture as R/W as we walk down the mip chain. RHICmdList.TransitionResources(EResourceTransitionAccess::ERWSubResBarrier, &HZBRenderTargetRef, 1); } GRenderTargetPool.VisualizeTexture.SetCheckPoint( RHICmdList, View.HZB ); }
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 FRCPassPostProcessEyeAdaptation::ComputeEyeAdaptationParamsValue(const FViewInfo& View, FVector4 Out[3]) { const FPostProcessSettings& Settings = View.FinalPostProcessSettings; const FEngineShowFlags& EngineShowFlags = View.Family->EngineShowFlags; float EyeAdaptationMin = Settings.AutoExposureMinBrightness; float EyeAdaptationMax = Settings.AutoExposureMaxBrightness; // FLT_MAX means no override float LocalOverrideExposure = FLT_MAX; // Eye adaptation is disabled except for highend right now because the histogram is not computed. if (!EngineShowFlags.EyeAdaptation || View.GetFeatureLevel() != ERHIFeatureLevel::SM5) { LocalOverrideExposure = 0; } float LocalExposureMultipler = pow(2, Settings.AutoExposureBias); if(View.Family->ExposureSettings.bFixed) { // editor wants to override the setting with it's own fixed setting LocalOverrideExposure = View.Family->ExposureSettings.LogOffset; LocalExposureMultipler = 1; } if(LocalOverrideExposure != FLT_MAX) { // set the eye adaptation to a fixed value EyeAdaptationMin = EyeAdaptationMax = FMath::Pow(2.0f, -LocalOverrideExposure); } if(EyeAdaptationMin > EyeAdaptationMax) { EyeAdaptationMin = EyeAdaptationMax; } float LowPercent = FMath::Clamp(Settings.AutoExposureLowPercent, 1.0f, 99.0f) * 0.01f; float HighPercent = FMath::Clamp(Settings.AutoExposureHighPercent, 1.0f, 99.0f) * 0.01f; if(LowPercent > HighPercent) { LowPercent = HighPercent; } Out[0] = FVector4(LowPercent, HighPercent, EyeAdaptationMin, EyeAdaptationMax); // ---------- Out[1] = FVector4(LocalExposureMultipler, View.Family->DeltaWorldTime, Settings.AutoExposureSpeedUp, Settings.AutoExposureSpeedDown); // ---------- // example min/max: -8 .. 4 means a range from 1/256 to 4 pow(2,-8) .. pow(2,4) float HistogramLogMin = Settings.HistogramLogMin; float HistogramLogMax = Settings.HistogramLogMax; float DeltaLog = HistogramLogMax - HistogramLogMin; float Multiply = 1.0f / DeltaLog; float Add = - HistogramLogMin * Multiply; Out[2] = FVector4(Multiply, Add, 0, 0); }
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); }
void FHZBOcclusionTester::Submit(FRHICommandListImmediate& RHICmdList, const FViewInfo& View) { SCOPED_DRAW_EVENT(RHICmdList, SubmitHZB); FSceneViewState* ViewState = (FSceneViewState*)View.State; if( !ViewState ) { return; } TRefCountPtr< IPooledRenderTarget > BoundsCenterTexture; TRefCountPtr< IPooledRenderTarget > BoundsExtentTexture; { uint32 Flags = TexCreate_ShaderResource | TexCreate_Dynamic; FPooledRenderTargetDesc Desc( FPooledRenderTargetDesc::Create2DDesc( FIntPoint( SizeX, SizeY ), PF_A32B32G32R32F, FClearValueBinding::None, Flags, TexCreate_None, false ) ); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, BoundsCenterTexture, TEXT("HZBBoundsCenter") ); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, BoundsExtentTexture, TEXT("HZBBoundsExtent") ); } TRefCountPtr< IPooledRenderTarget > ResultsTextureGPU; { FPooledRenderTargetDesc Desc( FPooledRenderTargetDesc::Create2DDesc( FIntPoint( SizeX, SizeY ), PF_B8G8R8A8, FClearValueBinding::None, TexCreate_None, TexCreate_RenderTargetable, false ) ); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, ResultsTextureGPU, TEXT("HZBResultsGPU") ); } { #if 0 static float CenterBuffer[ SizeX * SizeY ][4]; static float ExtentBuffer[ SizeX * SizeY ][4]; FMemory::Memset( CenterBuffer, 0, sizeof( CenterBuffer ) ); FMemory::Memset( ExtentBuffer, 0, sizeof( ExtentBuffer ) ); const uint32 NumPrimitives = Primitives.Num(); for( uint32 i = 0; i < NumPrimitives; i++ ) { const FOcclusionPrimitive& Primitive = Primitives[i]; CenterBuffer[i][0] = Primitive.Center.X; CenterBuffer[i][1] = Primitive.Center.Y; CenterBuffer[i][2] = Primitive.Center.Z; CenterBuffer[i][3] = 0.0f; ExtentBuffer[i][0] = Primitive.Extent.X; ExtentBuffer[i][1] = Primitive.Extent.Y; ExtentBuffer[i][2] = Primitive.Extent.Z; ExtentBuffer[i][3] = 1.0f; } FUpdateTextureRegion2D Region( 0, 0, 0, 0, SizeX, SizeY ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsCenterTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, SizeX * 4 * sizeof( float ), (uint8*)CenterBuffer ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsExtentTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, SizeX * 4 * sizeof( float ), (uint8*)ExtentBuffer ); #elif 0 static float CenterBuffer[ SizeX * SizeY ][4]; static float ExtentBuffer[ SizeX * SizeY ][4]; { QUICK_SCOPE_CYCLE_COUNTER(STAT_HZBPackPrimitiveData); FMemory::Memset( CenterBuffer, 0, sizeof( CenterBuffer ) ); FMemory::Memset( ExtentBuffer, 0, sizeof( ExtentBuffer ) ); const uint32 NumPrimitives = Primitives.Num(); for( uint32 i = 0; i < NumPrimitives; i++ ) { const FOcclusionPrimitive& Primitive = Primitives[i]; uint32 x = FMath::ReverseMortonCode2( i >> 0 ); uint32 y = FMath::ReverseMortonCode2( i >> 1 ); uint32 m = x + y * SizeX; CenterBuffer[m][0] = Primitive.Center.X; CenterBuffer[m][1] = Primitive.Center.Y; CenterBuffer[m][2] = Primitive.Center.Z; CenterBuffer[m][3] = 0.0f; ExtentBuffer[m][0] = Primitive.Extent.X; ExtentBuffer[m][1] = Primitive.Extent.Y; ExtentBuffer[m][2] = Primitive.Extent.Z; ExtentBuffer[m][3] = 1.0f; } } QUICK_SCOPE_CYCLE_COUNTER(STAT_HZBUpdateTextures); FUpdateTextureRegion2D Region( 0, 0, 0, 0, SizeX, SizeY ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsCenterTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, SizeX * 4 * sizeof( float ), (uint8*)CenterBuffer ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsExtentTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, SizeX * 4 * sizeof( float ), (uint8*)ExtentBuffer ); #else // Update in blocks to avoid large update const uint32 BlockSize = 8; const uint32 SizeInBlocksX = SizeX / BlockSize; const uint32 SizeInBlocksY = SizeY / BlockSize; const uint32 BlockStride = BlockSize * 4 * sizeof( float ); float CenterBuffer[ BlockSize * BlockSize ][4]; float ExtentBuffer[ BlockSize * BlockSize ][4]; const uint32 NumPrimitives = Primitives.Num(); for( uint32 i = 0; i < NumPrimitives; i += BlockSize * BlockSize ) { const uint32 BlockEnd = FMath::Min( BlockSize * BlockSize, NumPrimitives - i ); for( uint32 b = 0; b < BlockEnd; b++ ) { const FOcclusionPrimitive& Primitive = Primitives[ i + b ]; CenterBuffer[b][0] = Primitive.Center.X; CenterBuffer[b][1] = Primitive.Center.Y; CenterBuffer[b][2] = Primitive.Center.Z; CenterBuffer[b][3] = 0.0f; ExtentBuffer[b][0] = Primitive.Extent.X; ExtentBuffer[b][1] = Primitive.Extent.Y; ExtentBuffer[b][2] = Primitive.Extent.Z; ExtentBuffer[b][3] = 1.0f; } // Clear rest of block if( BlockEnd < BlockSize * BlockSize ) { FMemory::Memset( (float*)CenterBuffer + BlockEnd * 4, 0, sizeof( CenterBuffer ) - BlockEnd * 4 * sizeof(float) ); FMemory::Memset( (float*)ExtentBuffer + BlockEnd * 4, 0, sizeof( ExtentBuffer ) - BlockEnd * 4 * sizeof(float) ); } const int32 BlockIndex = i / (BlockSize * BlockSize); const int32 BlockX = BlockIndex % SizeInBlocksX; const int32 BlockY = BlockIndex / SizeInBlocksY; FUpdateTextureRegion2D Region( BlockX * BlockSize, BlockY * BlockSize, 0, 0, BlockSize, BlockSize ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsCenterTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, BlockStride, (uint8*)CenterBuffer ); RHIUpdateTexture2D( (FTexture2DRHIRef&)BoundsExtentTexture->GetRenderTargetItem().ShaderResourceTexture, 0, Region, BlockStride, (uint8*)ExtentBuffer ); } #endif Primitives.Empty(); } // Draw test { SCOPED_DRAW_EVENT(RHICmdList, TestHZB); SetRenderTarget(RHICmdList, ResultsTextureGPU->GetRenderTargetItem().TargetableTexture, NULL); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState< false, CF_Always >::GetRHI()); TShaderMapRef< FScreenVS > VertexShader(View.ShaderMap); TShaderMapRef< FHZBTestPS > PixelShader(View.ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, View, BoundsCenterTexture->GetRenderTargetItem().ShaderResourceTexture, BoundsExtentTexture->GetRenderTargetItem().ShaderResourceTexture ); RHICmdList.SetViewport(0, 0, 0.0f, SizeX, SizeY, 1.0f); // TODO draw quads covering blocks added above DrawRectangle( RHICmdList, 0, 0, SizeX, SizeY, 0, 0, SizeX, SizeY, FIntPoint( SizeX, SizeY ), FIntPoint( SizeX, SizeY ), *VertexShader, EDRF_UseTriangleOptimization); } GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, ResultsTextureGPU); // Transfer memory GPU -> CPU RHICmdList.CopyToResolveTarget(ResultsTextureGPU->GetRenderTargetItem().TargetableTexture, ResultsTextureCPU->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); }
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; } } }