Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/SceneOcclusion.h
2025-05-18 13:04:45 +08:00

136 lines
5.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Shader.h"
#include "GlobalShader.h"
#include "ShadowRendering.h"
#include "Engine/Engine.h"
class FProjectedShadowInfo;
class FPlanarReflectionSceneProxy;
class FRHIRenderQuery;
DECLARE_GPU_STAT_NAMED_EXTERN(HZB, TEXT("HZB"));
/*=============================================================================
SceneOcclusion.h
=============================================================================*/
struct FViewOcclusionQueries
{
using FProjectedShadowArray = TArray<FProjectedShadowInfo const*, SceneRenderingAllocator>;
using FPlanarReflectionArray = TArray<FPlanarReflectionSceneProxy const*, SceneRenderingAllocator>;
using FRenderQueryArray = TArray<FRHIRenderQuery*, SceneRenderingAllocator>;
FProjectedShadowArray LocalLightQueryInfos;
FProjectedShadowArray CSMQueryInfos;
FProjectedShadowArray ShadowQueryInfos;
FPlanarReflectionArray ReflectionQueryInfos;
FRenderQueryArray LocalLightQueries;
FRenderQueryArray CSMQueries;
FRenderQueryArray ShadowQueries;
FRenderQueryArray ReflectionQueries;
bool bFlushQueries = true;
};
using FViewOcclusionQueriesPerView = TArray<FViewOcclusionQueries, TInlineAllocator<1, SceneRenderingAllocator>>;
/**
* A vertex shader for rendering a texture on a simple element.
*/
class FOcclusionQueryVS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FOcclusionQueryVS,Global);
public:
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
static auto* MobileUseHWsRGBEncodingCVAR = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Mobile.UseHWsRGBEncoding"));
const bool bMobileUseHWsRGBEncoding = (MobileUseHWsRGBEncodingCVAR && MobileUseHWsRGBEncodingCVAR->GetValueOnAnyThread() == 1);
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
OutEnvironment.SetDefine(TEXT("OUTPUT_GAMMA_SPACE"), IsMobileHDR() == false && !bMobileUseHWsRGBEncoding);
OutEnvironment.SetDefine(TEXT("OUTPUT_MOBILE_HDR"), IsMobileHDR() == true);
}
FOcclusionQueryVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer):
FGlobalShader(Initializer)
{
StencilingGeometryParameters.Bind(Initializer.ParameterMap, TEXT("StencilingGeometryPosAndScale"));
}
FOcclusionQueryVS() {}
void SetParameters(FRHIBatchedShaderParameters& BatchedParameters, const FViewInfo& View, const FSphere& BoundingSphere)
{
FVector4f StencilingSpherePosAndScale[2];
StencilingGeometry::GStencilSphereVertexBuffer.CalcTransform(StencilingSpherePosAndScale[0], BoundingSphere, View.ViewMatrices.GetPreViewTranslation());
if (View.bShouldBindInstancedViewUB)
{
if (const FViewInfo* InstancedView = View.GetInstancedView())
{
StencilingGeometry::GStencilSphereVertexBuffer.CalcTransform(StencilingSpherePosAndScale[1], BoundingSphere, InstancedView->ViewMatrices.GetPreViewTranslation());
}
else
{
StencilingSpherePosAndScale[1] = StencilingSpherePosAndScale[0];
}
}
SetParametersInternal(BatchedParameters, View, StencilingSpherePosAndScale);
}
void SetParameters(FRHIBatchedShaderParameters& BatchedParameters, const FViewInfo& View)
{
// Don't transform if rendering frustum
FVector4f InstancedOffsetScale[2] = { FVector4f(0, 0, 0, 1), FVector4f(0, 0, 0, 1) };
if (View.bShouldBindInstancedViewUB)
{
// Occlusion queries are generated to be offset by the PreViewTranslation.
// However for multiview, we still need to apply that offset to the right eye.
// In that case we also need to undo the baked left eye translation.
if (const FViewInfo* InstancedView = View.GetInstancedView())
{
InstancedOffsetScale[1] = FVector4f(FVector3f(InstancedView->ViewMatrices.GetPreViewTranslation() - View.ViewMatrices.GetPreViewTranslation()), 1.0f);
}
}
SetParametersInternal(BatchedParameters, View, InstancedOffsetScale);
}
private:
void SetParametersInternal(FRHIBatchedShaderParameters& BatchedParameters, const FViewInfo& View, const FVector4f StencilingSpherePosAndScale[2])
{
FGlobalShader::SetParameters<FViewUniformShaderParameters>(BatchedParameters, View.ViewUniformBuffer);
if (!View.bShouldBindInstancedViewUB)
{
SetShaderValue(BatchedParameters, StencilingGeometryParameters, StencilingSpherePosAndScale[0]);
}
else
{
FGlobalShader::SetParameters<FInstancedViewUniformShaderParameters>(BatchedParameters, View.GetInstancedViewUniformBuffer());
SetShaderValueArray(BatchedParameters, StencilingGeometryParameters, StencilingSpherePosAndScale, 2);
}
}
private:
LAYOUT_FIELD(FShaderParameter, StencilingGeometryParameters)
};
/**
* A pixel shader for rendering a texture on a simple element.
*/
class FOcclusionQueryPS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FOcclusionQueryPS, Global);
public:
FOcclusionQueryPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) :
FGlobalShader(Initializer) {}
FOcclusionQueryPS() {}
};
// Returns whether occlusion queries should be downsampled.
extern RENDERER_API bool UseDownsampledOcclusionQueries();