// Copyright Epic Games, Inc. All Rights Reserved. #include "SparseVolumeTexture/SparseVolumeTextureViewerRendering.h" #include "SparseVolumeTexture/SparseVolumeTextureViewerSceneProxy.h" #include "SparseVolumeTexture/SparseVolumeTexture.h" #include "SceneView.h" #include "ScenePrivate.h" #include "SceneRendering.h" #include "RendererInterface.h" #include "UniformBuffer.h" #include "SceneTextureParameters.h" #include "ShaderCompiler.h" #include "RendererUtils.h" #include "EngineAnalytics.h" //////////////////////////////////////////////////////////////////////////////////////////////////// class FVisualizeSparseVolumeTextureVS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FVisualizeSparseVolumeTextureVS); SHADER_USE_PARAMETER_STRUCT(FVisualizeSparseVolumeTextureVS, FGlobalShader); using FPermutationDomain = TShaderPermutationDomain<>; BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER(float, DepthAsDeviceZ) END_SHADER_PARAMETER_STRUCT() static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector) { return PermutationVector; } static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return !IsMobilePlatform(Parameters.Platform) && EnumHasAllFlags(Parameters.Flags, EShaderPermutationFlags::HasEditorOnlyData); } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.SetDefine(TEXT("VERTEX_SHADER"), 1); } }; class FVisualizeSparseVolumeTexturePS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FVisualizeSparseVolumeTexturePS); SHADER_USE_PARAMETER_STRUCT(FVisualizeSparseVolumeTexturePS, FGlobalShader); using FPermutationDomain = TShaderPermutationDomain<>; BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, ViewUniformBuffer) RENDER_TARGET_BINDING_SLOTS() SHADER_PARAMETER(FVector3f, VolumeBoundMinWorld) SHADER_PARAMETER(FVector3f, VolumeBoundMaxWorld) SHADER_PARAMETER(FVector3f, SparseVolumeTextureResolution) SHADER_PARAMETER(FVector3f, SparseVolumeTexturePageTableResolution) SHADER_PARAMETER_TEXTURE(Texture3D, SparseVolumeTexture) SHADER_PARAMETER_TEXTURE(Texture3D, SparseVolumeTexturePageTable) END_SHADER_PARAMETER_STRUCT() static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector) { return PermutationVector; } static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return !IsMobilePlatform(Parameters.Platform) && EnumHasAllFlags(Parameters.Flags, EShaderPermutationFlags::HasEditorOnlyData); } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.SetDefine(TEXT("PIXEL_SHADER"), 1); } }; IMPLEMENT_GLOBAL_SHADER(FVisualizeSparseVolumeTextureVS, "/Engine/Private/SparseVolumeTexture/VisualizeSparseVolumeTexture.usf", "VisualizeSparseVolumeTextureVS", SF_Vertex); IMPLEMENT_GLOBAL_SHADER(FVisualizeSparseVolumeTexturePS, "/Engine/Private/SparseVolumeTexture/VisualizeSparseVolumeTexture.usf", "VisualizeSparseVolumeTexturePS", SF_Pixel); //////////////////////////////////////////////////////////////////////////////////////////////////// DECLARE_GPU_STAT(SparseVolumeTextureViewer); void AddSparseVolumeTextureViewerRenderPass(FRDGBuilder& GraphBuilder, FSceneRenderer& SceneRenderer, FSceneTextures& SceneTextures) { FScene* Scene = SceneRenderer.Scene; if (Scene->SparseVolumeTextureViewers.Num() == 0) { return; } RDG_EVENT_SCOPE(GraphBuilder, "SparseVolumeTextureViewer"); RDG_GPU_STAT_SCOPE(GraphBuilder, SparseVolumeTextureViewer); RDG_CSV_STAT_EXCLUSIVE_SCOPE(GraphBuilder, SparseVolumeTextureViewer); for (FViewInfo& View : SceneRenderer.Views) { const FIntRect& ViewportRect = View.ViewRect; for (auto& SVTProxy : Scene->SparseVolumeTextureViewers) { const FBoxSphereBounds& SVTProxyBound = SVTProxy->VolumeWorldBounds; FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); FVisualizeSparseVolumeTextureVS::FPermutationDomain VsPermutationVector; TShaderMapRef VertexShader(GlobalShaderMap, VsPermutationVector); FVisualizeSparseVolumeTexturePS::FPermutationDomain PsPermutationVector; TShaderMapRef PixelShader(GlobalShaderMap, PsPermutationVector); FVisualizeSparseVolumeTexturePS::FParameters* PsPassParameters = GraphBuilder.AllocParameters(); PsPassParameters->ViewUniformBuffer = View.ViewUniformBuffer; PsPassParameters->RenderTargets[0] = FRenderTargetBinding(SceneTextures.Color.Target, ERenderTargetLoadAction::ELoad); PsPassParameters->VolumeBoundMinWorld = FVector3f(SVTProxyBound.Origin - SVTProxyBound.BoxExtent); PsPassParameters->VolumeBoundMaxWorld = FVector3f(SVTProxyBound.Origin + SVTProxyBound.BoxExtent); PsPassParameters->SparseVolumeTextureResolution = FVector3f::OneVector; PsPassParameters->SparseVolumeTexturePageTableResolution = FVector3f::OneVector; PsPassParameters->SparseVolumeTexture = GBlackVolumeTexture->TextureRHI; PsPassParameters->SparseVolumeTexturePageTable = GBlackUintVolumeTexture->TextureRHI; if (SVTProxy->SparseVolumeTextureSceneProxy) { const FSparseVolumeAssetHeader& Header = SVTProxy->SparseVolumeTextureSceneProxy->GetHeader(); PsPassParameters->SparseVolumeTextureResolution = FVector3f(Header.SourceVolumeResolution); PsPassParameters->SparseVolumeTexturePageTableResolution = FVector3f(Header.PageTableVolumeResolution); FRHITexture* Texture = SVTProxy->SparseVolumeTextureSceneProxy->GetTileDataTextureRHI(); if (Texture) { PsPassParameters->SparseVolumeTexture = Texture; } FRHITexture* PageTableTexture = SVTProxy->SparseVolumeTextureSceneProxy->GetPageTableTextureRHI(); if (PageTableTexture) { PsPassParameters->SparseVolumeTexturePageTable = PageTableTexture; } } ClearUnusedGraphResources(PixelShader, PsPassParameters); float VsDepthAsDeviceZ = 0.1f; GraphBuilder.AddPass( {}, PsPassParameters, ERDGPassFlags::Raster, [PsPassParameters, VertexShader, PixelShader, ViewportRect, VsDepthAsDeviceZ](FRHICommandList& RHICmdListLambda) { RHICmdListLambda.SetViewport(ViewportRect.Min.X, ViewportRect.Min.Y, 0.0f, ViewportRect.Max.X, ViewportRect.Max.Y, 1.0f); FGraphicsPipelineStateInitializer GraphicsPSOInit; RHICmdListLambda.ApplyCachedRenderTargets(GraphicsPSOInit); GraphicsPSOInit.BlendState = TStaticBlendState::GetRHI(); GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); GraphicsPSOInit.RasterizerState = TStaticRasterizerState::GetRHI(); GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GEmptyVertexDeclaration.VertexDeclarationRHI; GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader(); GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader(); GraphicsPSOInit.PrimitiveType = PT_TriangleList; SetGraphicsPipelineState(RHICmdListLambda, GraphicsPSOInit, 0); SetShaderParameters(RHICmdListLambda, PixelShader, PixelShader.GetPixelShader(), *PsPassParameters); FVisualizeSparseVolumeTextureVS::FParameters VsPassParameters; VsPassParameters.DepthAsDeviceZ = VsDepthAsDeviceZ; SetShaderParameters(RHICmdListLambda, VertexShader, VertexShader.GetVertexShader(), VsPassParameters); RHICmdListLambda.DrawPrimitive(0, 1, 1); }); } } }