You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#jira UE-69272 #rb Daniel.Wright #ROBOMERGE-OWNER: ryan.vance #ROBOMERGE-AUTHOR: jules.blok #ROBOMERGE-SOURCE: CL 4871742 in //UE4/Main/... #ROBOMERGE-BOT: DEVVR (Main -> Dev-VR) [CL 4871746 by jules blok in Dev-VR branch]
199 lines
9.3 KiB
C++
199 lines
9.3 KiB
C++
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
CustomDepthRendering.cpp: CustomDepth rendering implementation.
|
|
=============================================================================*/
|
|
|
|
#include "SceneUtils.h"
|
|
#include "DepthRendering.h"
|
|
#include "SceneRendering.h"
|
|
#include "SceneCore.h"
|
|
#include "ScenePrivate.h"
|
|
#include "MeshPassProcessor.inl"
|
|
|
|
class FCustomDepthPassMeshProcessor : public FMeshPassProcessor
|
|
{
|
|
public:
|
|
FCustomDepthPassMeshProcessor(const FScene* Scene, const FSceneView* InViewIfDynamicMeshCommand, FMeshPassDrawListContext* InDrawListContext);
|
|
|
|
virtual void AddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId = -1) override final;
|
|
|
|
private:
|
|
template<bool bPositionOnly>
|
|
void Process(
|
|
const FMeshBatch& MeshBatch,
|
|
uint64 BatchElementMask,
|
|
int32 StaticMeshId,
|
|
const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy,
|
|
const FMaterialRenderProxy& RESTRICT MaterialRenderProxy,
|
|
const FMaterial& RESTRICT MaterialResource,
|
|
ERasterizerFillMode MeshFillMode,
|
|
ERasterizerCullMode MeshCullMode,
|
|
float MobileColorValue,
|
|
bool bUsesMobileColorValue);
|
|
|
|
FMeshPassProcessorRenderState PassDrawRenderState;
|
|
};
|
|
|
|
FCustomDepthPassMeshProcessor::FCustomDepthPassMeshProcessor(const FScene* Scene, const FSceneView* InViewIfDynamicMeshCommand, FMeshPassDrawListContext* InDrawListContext)
|
|
: FMeshPassProcessor(Scene, Scene->GetFeatureLevel(), InViewIfDynamicMeshCommand, InDrawListContext)
|
|
{
|
|
PassDrawRenderState.SetViewUniformBuffer(Scene->UniformBuffers.CustomDepthViewUniformBuffer);
|
|
|
|
if (FSceneInterface::GetShadingPath(FeatureLevel) == EShadingPath::Mobile)
|
|
{
|
|
PassDrawRenderState.SetPassUniformBuffer(Scene->UniformBuffers.MobileCustomDepthPassUniformBuffer);
|
|
}
|
|
else
|
|
{
|
|
PassDrawRenderState.SetPassUniformBuffer(Scene->UniformBuffers.CustomDepthPassUniformBuffer);
|
|
}
|
|
|
|
PassDrawRenderState.SetBlendState(TStaticBlendState<>::GetRHI());
|
|
PassDrawRenderState.SetDepthStencilState(TStaticDepthStencilState<true, CF_DepthNearOrEqual>::GetRHI());
|
|
}
|
|
|
|
void FCustomDepthPassMeshProcessor::AddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId)
|
|
{
|
|
if (PrimitiveSceneProxy->ShouldRenderCustomDepth())
|
|
{
|
|
// Determine the mesh's material and blend mode.
|
|
const FMaterialRenderProxy* FallbackMaterialRenderProxyPtr = nullptr;
|
|
const FMaterial& Material = MeshBatch.MaterialRenderProxy->GetMaterialWithFallback(FeatureLevel, FallbackMaterialRenderProxyPtr);
|
|
const FMaterialRenderProxy& MaterialRenderProxy = FallbackMaterialRenderProxyPtr ? *FallbackMaterialRenderProxyPtr : *MeshBatch.MaterialRenderProxy;
|
|
|
|
const EBlendMode BlendMode = Material.GetBlendMode();
|
|
const ERasterizerFillMode MeshFillMode = ComputeMeshFillMode(MeshBatch, Material);
|
|
const ERasterizerCullMode MeshCullMode = ComputeMeshCullMode(MeshBatch, Material);
|
|
const bool bIsTranslucent = IsTranslucentBlendMode(BlendMode);
|
|
|
|
|
|
const bool bWriteCustomStencilValues = FSceneRenderTargets::IsCustomDepthPassWritingStencil();
|
|
float bMobileColorValue = 0.0f;
|
|
|
|
if (bWriteCustomStencilValues)
|
|
{
|
|
const uint32 CustomDepthStencilValue = PrimitiveSceneProxy->GetCustomDepthStencilValue();
|
|
const static FDepthStencilStateRHIParamRef StencilStates[EStencilMask::SM_Count] =
|
|
{
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 255>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 255>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 1>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 2>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 4>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 8>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 16>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 32>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 64>::GetRHI(),
|
|
TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Replace, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 128>::GetRHI()
|
|
};
|
|
checkSlow(EStencilMask::SM_Count == ARRAY_COUNT(StencilStates));
|
|
|
|
PassDrawRenderState.SetDepthStencilState(StencilStates[(int32)PrimitiveSceneProxy->GetStencilWriteMask()]);
|
|
PassDrawRenderState.SetStencilRef(CustomDepthStencilValue);
|
|
|
|
if (FeatureLevel <= ERHIFeatureLevel::ES3_1)
|
|
{
|
|
// On mobile platforms write custom stencil value to color target
|
|
bMobileColorValue = CustomDepthStencilValue / 255.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PassDrawRenderState.SetDepthStencilState(TStaticDepthStencilState<true, CF_DepthNearOrEqual>::GetRHI());
|
|
}
|
|
|
|
const bool bUsesMobileColorValue = bMobileColorValue != 0.0f;
|
|
|
|
|
|
if (BlendMode == BLEND_Opaque
|
|
&& MeshBatch.VertexFactory->SupportsPositionOnlyStream()
|
|
&& !Material.MaterialModifiesMeshPosition_RenderThread()
|
|
&& Material.WritesEveryPixel()
|
|
&& !bUsesMobileColorValue)
|
|
{
|
|
const FMaterialRenderProxy& DefaultProxy = *UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy();
|
|
const FMaterial& DefaultMaterial = *DefaultProxy.GetMaterial(FeatureLevel);
|
|
Process<true>(MeshBatch, BatchElementMask, StaticMeshId, PrimitiveSceneProxy, DefaultProxy, DefaultMaterial, MeshFillMode, MeshCullMode, bMobileColorValue, bUsesMobileColorValue);
|
|
}
|
|
else if (!IsTranslucentBlendMode(BlendMode) || Material.IsTranslucencyWritingCustomDepth())
|
|
{
|
|
const bool bMaterialMasked = !Material.WritesEveryPixel() || Material.IsTranslucencyWritingCustomDepth();
|
|
|
|
const FMaterialRenderProxy* EffectiveMaterialRenderProxy = &MaterialRenderProxy;
|
|
const FMaterial* EffectiveMaterial = &Material;
|
|
|
|
if (!bMaterialMasked && !Material.MaterialModifiesMeshPosition_RenderThread())
|
|
{
|
|
// Override with the default material for opaque materials that are not two sided
|
|
EffectiveMaterialRenderProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy();
|
|
EffectiveMaterial = EffectiveMaterialRenderProxy->GetMaterial(FeatureLevel);
|
|
}
|
|
|
|
Process<false>(MeshBatch, BatchElementMask, StaticMeshId, PrimitiveSceneProxy, *EffectiveMaterialRenderProxy, *EffectiveMaterial, MeshFillMode, MeshCullMode, bMobileColorValue, bUsesMobileColorValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<bool bPositionOnly>
|
|
void FCustomDepthPassMeshProcessor::Process(
|
|
const FMeshBatch& RESTRICT MeshBatch,
|
|
uint64 BatchElementMask,
|
|
int32 StaticMeshId,
|
|
const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy,
|
|
const FMaterialRenderProxy& RESTRICT MaterialRenderProxy,
|
|
const FMaterial& RESTRICT MaterialResource,
|
|
ERasterizerFillMode MeshFillMode,
|
|
ERasterizerCullMode MeshCullMode,
|
|
float MobileColorValue,
|
|
bool bUsesMobileColorValue)
|
|
{
|
|
const FVertexFactory* VertexFactory = MeshBatch.VertexFactory;
|
|
|
|
TMeshProcessorShaders<
|
|
TDepthOnlyVS<bPositionOnly>,
|
|
FDepthOnlyHS,
|
|
FDepthOnlyDS,
|
|
FDepthOnlyPS> DepthPassShaders;
|
|
|
|
FShaderPipeline* ShaderPipeline = nullptr;
|
|
|
|
GetDepthPassShaders<bPositionOnly>(
|
|
MaterialResource,
|
|
VertexFactory->GetType(),
|
|
FeatureLevel,
|
|
DepthPassShaders.HullShader,
|
|
DepthPassShaders.DomainShader,
|
|
DepthPassShaders.VertexShader,
|
|
DepthPassShaders.PixelShader,
|
|
ShaderPipeline,
|
|
bUsesMobileColorValue
|
|
);
|
|
|
|
FDepthOnlyShaderElementData ShaderElementData(MobileColorValue);
|
|
ShaderElementData.InitializeMeshMaterialData(ViewIfDynamicMeshCommand, PrimitiveSceneProxy, MeshBatch, StaticMeshId, false);
|
|
|
|
const FMeshDrawCommandSortKey SortKey = CalculateMeshStaticSortKey(DepthPassShaders.VertexShader, DepthPassShaders.PixelShader);
|
|
|
|
BuildMeshDrawCommands(
|
|
MeshBatch,
|
|
BatchElementMask,
|
|
PrimitiveSceneProxy,
|
|
MaterialRenderProxy,
|
|
MaterialResource,
|
|
PassDrawRenderState,
|
|
DepthPassShaders,
|
|
MeshFillMode,
|
|
MeshCullMode,
|
|
SortKey,
|
|
bPositionOnly ? EMeshPassFeatures::PositionOnly : EMeshPassFeatures::Default,
|
|
ShaderElementData);
|
|
}
|
|
|
|
FMeshPassProcessor* CreateCustomDepthPassProcessor(const FScene* Scene, const FSceneView* InViewIfDynamicMeshCommand, FMeshPassDrawListContext* InDrawListContext)
|
|
{
|
|
return new(FMemStack::Get()) FCustomDepthPassMeshProcessor(Scene, InViewIfDynamicMeshCommand, InDrawListContext);
|
|
}
|
|
|
|
FRegisterPassProcessorCreateFunction RegisterCustomDepthPass(&CreateCustomDepthPassProcessor, EShadingPath::Deferred, EMeshPass::CustomDepth, EMeshPassFlags::MainView);
|
|
FRegisterPassProcessorCreateFunction RegisterMobileCustomDepthPass(&CreateCustomDepthPassProcessor, EShadingPath::Mobile, EMeshPass::CustomDepth, EMeshPassFlags::MainView); |