You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
The refactor to get rid of the FSceneTextures and FSceneTexturesConfig global singletons has also been preserved. The FViewFamilyInfo is used to hold those structures, so client facing API functions that lack a scene renderer reference can still pull the FSceneTextures[Config] from the view family pointer. All other scene renderer state has been moved from FViewFamilyInfo back into FSceneRenderer. #jira none #rnx #rb ola.olsson krzysztof.narkowicz zach.bethel #preflight 629f770e233ae0a8f8fb7f2e [CL 20540730 by jason hoerner in ue5-main branch]
117 lines
4.9 KiB
C++
117 lines
4.9 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
MobileDecalRendering.cpp: Decals for mobile renderer
|
|
=============================================================================*/
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Stats/Stats.h"
|
|
#include "RHIDefinitions.h"
|
|
#include "RHI.h"
|
|
#include "SceneUtils.h"
|
|
#include "RHIStaticStates.h"
|
|
#include "PostProcess/SceneRenderTargets.h"
|
|
#include "SceneRendering.h"
|
|
#include "ScenePrivate.h"
|
|
#include "DecalRenderingCommon.h"
|
|
#include "DecalRenderingShared.h"
|
|
|
|
void RenderMeshDecalsMobile(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, EDecalRenderStage DecalRenderStage, EDecalRenderTargetMode RenderTargetMode);
|
|
extern void RenderDeferredDecalsMobile(FRHICommandListImmediate& RHICmdList, const FScene& Scene, const FViewInfo& View, EDecalRenderStage DecalRenderStage, EDecalRenderTargetMode RenderTargetMode);
|
|
|
|
void FMobileSceneRenderer::RenderDecals(FRHICommandListImmediate& RHICmdList, const FViewInfo& View)
|
|
{
|
|
if (!IsMobileHDR() || !ViewFamily.EngineShowFlags.Decals || View.bIsPlanarReflection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CSV_SCOPED_TIMING_STAT_EXCLUSIVE(RenderDecals);
|
|
SCOPE_CYCLE_COUNTER(STAT_DecalsDrawTime);
|
|
|
|
const bool bIsMobileDeferred = IsMobileDeferredShadingEnabled(View.GetShaderPlatform());
|
|
const EDecalRenderStage DecalRenderStage = bIsMobileDeferred ? EDecalRenderStage::MobileBeforeLighting : EDecalRenderStage::Mobile;
|
|
const EDecalRenderTargetMode RenderTargetMode = bIsMobileDeferred ? EDecalRenderTargetMode::SceneColorAndGBuffer : EDecalRenderTargetMode::SceneColor;
|
|
|
|
// Deferred decals
|
|
if (Scene->Decals.Num() > 0)
|
|
{
|
|
SCOPED_DRAW_EVENT(RHICmdList, Decals);
|
|
RenderDeferredDecalsMobile(RHICmdList, *Scene, View, DecalRenderStage, RenderTargetMode);
|
|
}
|
|
|
|
// Mesh decals
|
|
if (View.MeshDecalBatches.Num() > 0)
|
|
{
|
|
SCOPED_DRAW_EVENT(RHICmdList, MeshDecals);
|
|
RenderMeshDecalsMobile(RHICmdList, View, DecalRenderStage, RenderTargetMode);
|
|
}
|
|
}
|
|
|
|
void RenderDeferredDecalsMobile(FRHICommandListImmediate& RHICmdList, const FScene& Scene, const FViewInfo& View, EDecalRenderStage DecalRenderStage, EDecalRenderTargetMode RenderTargetMode)
|
|
{
|
|
const uint32 DecalCount = Scene.Decals.Num();
|
|
int32 SortedDecalCount = 0;
|
|
FTransientDecalRenderDataList SortedDecals;
|
|
|
|
if (DecalCount > 0)
|
|
{
|
|
// Build a list of decals that need to be rendered for this view
|
|
DecalRendering::BuildVisibleDecalList(Scene, View, DecalRenderStage, &SortedDecals);
|
|
SortedDecalCount = SortedDecals.Num();
|
|
INC_DWORD_STAT_BY(STAT_Decals, SortedDecalCount);
|
|
}
|
|
|
|
if (SortedDecalCount > 0)
|
|
{
|
|
FGraphicsPipelineStateInitializer GraphicsPSOInit;
|
|
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
|
|
|
|
RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1);
|
|
RHICmdList.SetStreamSource(0, GetUnitCubeVertexBuffer(), 0);
|
|
|
|
for (int32 DecalIndex = 0; DecalIndex < SortedDecalCount; DecalIndex++)
|
|
{
|
|
const FTransientDecalRenderData& DecalData = SortedDecals[DecalIndex];
|
|
const FDeferredDecalProxy& DecalProxy = DecalData.Proxy;
|
|
const FMatrix ComponentToWorldMatrix = DecalProxy.ComponentTrans.ToMatrixWithScale();
|
|
const FMatrix FrustumComponentToClip = DecalRendering::ComputeComponentToClipMatrix(View, ComponentToWorldMatrix);
|
|
|
|
const float ConservativeRadius = DecalData.ConservativeRadius;
|
|
const bool bInsideDecal = ((FVector)View.ViewMatrices.GetViewOrigin() - ComponentToWorldMatrix.GetOrigin()).SizeSquared() < FMath::Square(ConservativeRadius * 1.05f + View.NearClippingDistance * 2.0f);
|
|
bool bReverseHanded = false;
|
|
{
|
|
// Account for the reversal of handedness caused by negative scale on the decal
|
|
const auto& Scale3d = DecalProxy.ComponentTrans.GetScale3D();
|
|
bReverseHanded = Scale3d[0] * Scale3d[1] * Scale3d[2] < 0.f;
|
|
}
|
|
EDecalRasterizerState DecalRasterizerState = DecalRendering::GetDecalRasterizerState(bInsideDecal, bReverseHanded, View.bReverseCulling);
|
|
GraphicsPSOInit.RasterizerState = DecalRendering::GetDecalRasterizerState(DecalRasterizerState);
|
|
|
|
if (bInsideDecal)
|
|
{
|
|
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<
|
|
false, CF_Always,
|
|
true, CF_Equal, SO_Keep, SO_Keep, SO_Keep,
|
|
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
|
GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1), 0x00>::GetRHI();
|
|
}
|
|
else
|
|
{
|
|
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<
|
|
false, CF_DepthNearOrEqual,
|
|
true, CF_Equal, SO_Keep, SO_Keep, SO_Keep,
|
|
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
|
GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1), 0x00>::GetRHI();
|
|
}
|
|
|
|
GraphicsPSOInit.BlendState = DecalRendering::GetDecalBlendState(DecalData.BlendDesc, DecalRenderStage, RenderTargetMode);
|
|
|
|
// Set shader params
|
|
DecalRendering::SetShader(RHICmdList, GraphicsPSOInit, 0, View, DecalData, DecalRenderStage, FrustumComponentToClip);
|
|
|
|
RHICmdList.DrawIndexedPrimitive(GetUnitCubeIndexBuffer(), 0, 0, 8, 0, UE_ARRAY_COUNT(GCubeIndices) / 3, 1);
|
|
}
|
|
}
|
|
}
|