Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/ConvertToUniformMesh.cpp
Andrew Grant d077828526 Copying //UE4/Orion-Staging to Dev-Main (Originating from //Orion/Main at CL-2777663)
#lockdown Nick.Penwarden

 Change 2777555 on 2015/11/23 by Antony.Carter

	Friend List Sub Menu restyling to new designs

	#RB Nicholas.Davies
	#TESTS Check 3 sub menus of friends list (Online Status, Friends List, Settings) still function correctly with new styling.

Change 2777506 on 2015/11/23 by Andrew.Rodham

	Sequencer: Copy/Paste command binding is no longer active if the seuqnece widget is not focused

	This addresses UE-23423

	#tests Tested copy/paste inside and outside of sequencer
	#codereview Max.Chen
	#rb Max.Chen

Change 2777505 on 2015/11/23 by Andrew.Rodham

	Sequencer: Undoing the addition of a spawnable now ensures its actor instance is deleted correctly

	This addresses UE-23450

	#tests tested the repro steps on the bug
	#codereview Max.Chen
	#rb Max.Chen

Change 2777489 on 2015/11/23 by Andrew.Rodham

	Sequencer: Workflow optimizations for spawnables

	 - Editing a property on an instance of a spawnable now automatically propagates to the spawnable defaults, provided the property is not keyed
	 - Fixed a few cases where spawnables were left lingering around while scrubbing or switching between sub-sequences
	 - Fixed the root sequence instance being evaluated when there was a sub-sequence focused.
	 - Selection states are now remembered for spawnable objects when they are destroyed/re-spawned

	#codereview Max.Chen
	#tests tested loks of object types as spawnables in PIE and in editor
	#rb Max.Chen

Change 2777321 on 2015/11/23 by Terence.Burns

	Updated the usage of World->UpdateStreamingLevels to FlushStreaming levels on the advice of Dmitriy. Need this to ensure that the streaming is completed before we send it off to lightmass.

	#rb Dmitriy.Dyomin
	#Tests Run the RebuildLightmaps UAT script.

Change 2777091 on 2015/11/22 by Andrew.Grant

	Changed "inappropriate outmost" warning on package load to an error. At the very least we want this for a day or two on Orion to surface errors quickly, but may be a good thing to make a standard error since it indicates something that's likely broken.

	#rb none
	#tests Golden path in game, cooked content
	#codereview Nick.Penwarden, Michael.Noland

Change 2777037 on 2015/11/22 by Laurent.Delayen

	Additional debug info to track down https://jira.ol.epicgames.net/browse/OR-9675

	#rb martin.wilson
	#codereview martin.wilson
	#tests Golden path (PIE) + compiled for PS4

Change 2777030 on 2015/11/22 by Sam.Zamani

	#online,externalui,ps4
	- added footer option for closing the embedded web browser

	#rb none
	#tests exec command to try on ps4

Change 2777019 on 2015/11/22 by Marcus.Wassmer

	Possible fix for OR-9851
	#rb none
	#test GoldenPath, PS4
	#codereview Nick.Darnell,Matt.Kuhlenschmidt

Change 2776932 on 2015/11/22 by Max.Chen

	Sequencer: Fix editor selection so that it's not modified in response to the sequencer outliner tree node changing selection if the user is not explicitly selecting in the tree.

	#RB none
	#tests Select an actor that Sequencer doesn't control and it shouldn't deselect.

Change 2776900 on 2015/11/21 by Marcus.Wassmer

	HighQuality particle lights.
	#rb Brian.Karis
	#test GoldenPath, HQ Particles w/wo ShadowCasting.
	#codereview Olaf.Piesche, Simon.Tovey, Tim.Elek

Change 2776868 on 2015/11/21 by Brian.Karis

	Reduced temporal aa responsiveness back where it was.

Change 2776867 on 2015/11/21 by Brian.Karis

	Removed shading terminator bias meant for shadow map acne but it made character faces look worse.

Change 2776840 on 2015/11/21 by Brian.Karis

	Hair indirect lighting implemented.

	Improvements to hair shading model. No longer uses backlit parameter.

	#rb marcus.wassmer
	#tests editor

Change 2776748 on 2015/11/21 by Max.Preussner

	Sequencer: Continued to implement track label editor

	Note: still disabled, because there are a couple remaining issues

	#codereview: max.chen
	#rb: max.chen
	#test: Editor, Runtime

Change 2776493 on 2015/11/20 by Max.Preussner

	Sequencer: Wrapped the node tree context menu actions for editing in an 'Edit' section

	#codereview: max.chen
	#rb: max.chen
2015-11-24 16:45:24 -05:00

495 lines
18 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
ConvertToUniformMesh.cpp
=============================================================================*/
#include "RendererPrivate.h"
#include "ScenePrivate.h"
#include "UniformBuffer.h"
#include "ShaderParameters.h"
#include "PostProcessing.h"
#include "SceneFilterRendering.h"
#include "DistanceFieldLightingShared.h"
#include "DistanceFieldSurfaceCacheLighting.h"
#include "DistanceFieldGlobalIllumination.h"
#include "RHICommandList.h"
#include "SceneUtils.h"
#include "DistanceFieldAtlas.h"
class FConvertToUniformMeshVS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FConvertToUniformMeshVS,MeshMaterial);
protected:
FConvertToUniformMeshVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{
}
FConvertToUniformMeshVS()
{
}
static bool ShouldCache(EShaderPlatform Platform,const FMaterial* Material,const FVertexFactoryType* VertexFactoryType)
{
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5)
&& DoesPlatformSupportDistanceFieldGI(Platform)
&& (FCString::Strstr(VertexFactoryType->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(VertexFactoryType->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
public:
void SetParameters(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FMaterialRenderProxy* MaterialRenderProxy,const FSceneView* View)
{
FMeshMaterialShader::SetParameters(RHICmdList, GetVertexShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View->GetFeatureLevel()), *View, ESceneRenderTargetsMode::SetTextures);
}
void SetMesh(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FSceneView& View,const FPrimitiveSceneProxy* Proxy,const FMeshBatchElement& BatchElement, float DitheredLODTransitionValue)
{
FMeshMaterialShader::SetMesh(RHICmdList, GetVertexShader(),VertexFactory,View,Proxy,BatchElement,DitheredLODTransitionValue);
}
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FConvertToUniformMeshVS,TEXT("ConvertToUniformMesh"),TEXT("ConvertToUniformMeshVS"),SF_Vertex);
void GetUniformMeshStreamOutLayout(FStreamOutElementList& Layout)
{
Layout.Add(FStreamOutElement(0, "SV_Position", 0, 4, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 0, 3, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 1, 3, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 2, 3, 0));
Layout.Add(FStreamOutElement(0, "UV", 0, 2, 0));
Layout.Add(FStreamOutElement(0, "UV", 1, 2, 0));
Layout.Add(FStreamOutElement(0, "VertexColor", 0, 4, 0));
}
// In float4's, must match usf
int32 FSurfelBuffers::InterpolatedVertexDataStride = 6;
/** Returns number of float's in the uniform vertex. */
int32 ComputeUniformVertexStride()
{
FStreamOutElementList Layout;
int32 StreamStride = 0;
GetUniformMeshStreamOutLayout(Layout);
for (int32 ElementIndex = 0; ElementIndex < Layout.Num(); ElementIndex++)
{
StreamStride += Layout[ElementIndex].ComponentCount;
}
// D3D11 stream out buffer element stride must be a factor of 4
return FMath::DivideAndRoundUp(StreamStride, 4) * 4;
}
void FUniformMeshBuffers::Initialize()
{
if (MaxElements > 0)
{
const int32 VertexStride = ComputeUniformVertexStride();
FRHIResourceCreateInfo CreateInfo;
TriangleData = RHICreateVertexBuffer(MaxElements * VertexStride * GPixelFormats[PF_R32_FLOAT].BlockBytes, BUF_ShaderResource | BUF_StreamOutput, CreateInfo);
TriangleDataSRV = RHICreateShaderResourceView(TriangleData, GPixelFormats[PF_R32_FLOAT].BlockBytes, PF_R32_FLOAT);
TriangleAreas.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
TriangleCDFs.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
}
}
class FConvertToUniformMeshGS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FConvertToUniformMeshGS,MeshMaterial);
protected:
FConvertToUniformMeshGS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{
}
FConvertToUniformMeshGS()
{
}
static bool ShouldCache(EShaderPlatform Platform,const FMaterial* Material,const FVertexFactoryType* VertexFactoryType)
{
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5)
&& DoesPlatformSupportDistanceFieldGI(Platform)
&& (FCString::Strstr(VertexFactoryType->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(VertexFactoryType->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
static void GetStreamOutElements(FStreamOutElementList& ElementList, TArray<uint32>& StreamStrides, int32& RasterizedStream)
{
StreamStrides.Add(ComputeUniformVertexStride() * 4);
GetUniformMeshStreamOutLayout(ElementList);
RasterizedStream = -1;
}
public:
void SetParameters(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FMaterialRenderProxy* MaterialRenderProxy,const FSceneView* View)
{
FMeshMaterialShader::SetParameters(RHICmdList, (FGeometryShaderRHIParamRef)GetGeometryShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View->GetFeatureLevel()), *View, ESceneRenderTargetsMode::SetTextures);
}
void SetMesh(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FSceneView& View,const FPrimitiveSceneProxy* Proxy,const FMeshBatchElement& BatchElement, float DitheredLODTransitionValue)
{
FMeshMaterialShader::SetMesh(RHICmdList, (FGeometryShaderRHIParamRef)GetGeometryShader(),VertexFactory,View,Proxy,BatchElement,DitheredLODTransitionValue);
}
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FConvertToUniformMeshGS,TEXT("ConvertToUniformMesh"),TEXT("ConvertToUniformMeshGS"),SF_Geometry);
class FConvertToUniformMeshDrawingPolicy : public FMeshDrawingPolicy
{
public:
/** context type */
typedef FMeshDrawingPolicy::ElementDataType ElementDataType;
/**
* Constructor
* @param InIndexBuffer - index buffer for rendering
* @param InVertexFactory - vertex factory for rendering
* @param InMaterialRenderProxy - material instance for rendering
* @param bInOverrideWithShaderComplexity - whether to override with shader complexity
*/
FConvertToUniformMeshDrawingPolicy(
const FVertexFactory* InVertexFactory,
const FMaterialRenderProxy* InMaterialRenderProxy,
const FMaterial& MaterialResouce,
ERHIFeatureLevel::Type InFeatureLevel
);
// FMeshDrawingPolicy interface.
/**
* Match two draw policies
* @param Other - draw policy to compare
* @return true if the draw policies are a match
*/
bool Matches(const FConvertToUniformMeshDrawingPolicy& Other) const;
/**
* Executes the draw commands which can be shared between any meshes using this drawer.
* @param CI - The command interface to execute the draw commands on.
* @param View - The view of the scene being drawn.
*/
void SetSharedState(FRHICommandList& RHICmdList, const FSceneView* View, const ContextDataType PolicyContext) const;
/**
* Create bound shader state using the vertex decl from the mesh draw policy
* as well as the shaders needed to draw the mesh
* @return new bound shader state object
*/
FBoundShaderStateInput GetBoundShaderStateInput(ERHIFeatureLevel::Type InFeatureLevel);
/**
* Sets the render states for drawing a mesh.
* @param PrimitiveSceneProxy - The primitive drawing the dynamic mesh. If this is a view element, this will be NULL.
* @param Mesh - mesh element with data needed for rendering
* @param ElementData - context specific data for mesh rendering
*/
void SetMeshRenderState(
FRHICommandList& RHICmdList,
const FSceneView& View,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMeshBatch& Mesh,
int32 BatchElementIndex,
bool bBackFace,
float DitheredLODTransitionValue,
const ElementDataType& ElementData,
const ContextDataType PolicyContext
) const;
private:
FConvertToUniformMeshVS* VertexShader;
FConvertToUniformMeshGS* GeometryShader;
};
FConvertToUniformMeshDrawingPolicy::FConvertToUniformMeshDrawingPolicy(
const FVertexFactory* InVertexFactory,
const FMaterialRenderProxy* InMaterialRenderProxy,
const FMaterial& InMaterialResource,
ERHIFeatureLevel::Type InFeatureLevel
)
: FMeshDrawingPolicy(InVertexFactory,InMaterialRenderProxy,InMaterialResource,false)
{
VertexShader = InMaterialResource.GetShader<FConvertToUniformMeshVS>(InVertexFactory->GetType());
GeometryShader = InMaterialResource.GetShader<FConvertToUniformMeshGS>(InVertexFactory->GetType());
}
bool FConvertToUniformMeshDrawingPolicy::Matches(
const FConvertToUniformMeshDrawingPolicy& Other
) const
{
return FMeshDrawingPolicy::Matches(Other) &&
VertexShader == Other.VertexShader &&
GeometryShader == Other.GeometryShader;
}
void FConvertToUniformMeshDrawingPolicy::SetSharedState(
FRHICommandList& RHICmdList,
const FSceneView* View,
const ContextDataType PolicyContext
) const
{
// Set shared mesh resources
FMeshDrawingPolicy::SetSharedState(RHICmdList, View, PolicyContext);
VertexShader->SetParameters(RHICmdList, VertexFactory, MaterialRenderProxy, View);
GeometryShader->SetParameters(RHICmdList, VertexFactory, MaterialRenderProxy, View);
}
FBoundShaderStateInput FConvertToUniformMeshDrawingPolicy::GetBoundShaderStateInput(ERHIFeatureLevel::Type InFeatureLevel)
{
return FBoundShaderStateInput(
FMeshDrawingPolicy::GetVertexDeclaration(),
VertexShader->GetVertexShader(),
NULL,
NULL,
NULL,
GeometryShader->GetGeometryShader());
}
void FConvertToUniformMeshDrawingPolicy::SetMeshRenderState(
FRHICommandList& RHICmdList,
const FSceneView& View,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMeshBatch& Mesh,
int32 BatchElementIndex,
bool bBackFace,
float DitheredLODTransitionValue,
const ElementDataType& ElementData,
const ContextDataType PolicyContext
) const
{
const FMeshBatchElement& BatchElement = Mesh.Elements[BatchElementIndex];
// Set transforms
VertexShader->SetMesh(RHICmdList, VertexFactory,View,PrimitiveSceneProxy,BatchElement, DitheredLODTransitionValue);
GeometryShader->SetMesh(RHICmdList, VertexFactory,View,PrimitiveSceneProxy,BatchElement, DitheredLODTransitionValue);
// Set rasterizer state.
RHICmdList.SetRasterizerState(GetStaticRasterizerState<true>(
(Mesh.bWireframe || IsWireframe()) ? FM_Wireframe : FM_Solid,
IsTwoSided() ? CM_None : (XOR( XOR(View.bReverseCulling,bBackFace), Mesh.ReverseCulling) ? CM_CCW : CM_CW)));
}
bool ShouldGenerateSurfelsOnMesh(const FMeshBatch& Mesh, ERHIFeatureLevel::Type FeatureLevel)
{
//@todo - support for tessellated meshes
return Mesh.Type == PT_TriangleList
&& !Mesh.IsTranslucent(FeatureLevel)
&& Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel)->GetShadingModel() != MSM_Unlit;
}
bool ShouldConvertMesh(const FMeshBatch& Mesh)
{
return Mesh.Type == PT_TriangleList
//@todo - import types and compare directly
&& (FCString::Strstr(Mesh.VertexFactory->GetType()->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(Mesh.VertexFactory->GetType()->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
FUniformMeshBuffers GUniformMeshTemporaryBuffers;
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,0.0f,FConvertToUniformMeshDrawingPolicy::ElementDataType(), FConvertToUniformMeshDrawingPolicy::ContextDataType());
DrawingPolicy.DrawMesh(RHICmdList, Mesh, BatchElementIndex);
}
}
}
RHICmdList.SetStreamOutTargets(1, (const FVertexBufferRHIParamRef*)NULL, Offsets);
}
OutUniformMeshBuffers = &GUniformMeshTemporaryBuffers;
return NumTriangles;
}
int32 GEvaluateSurfelMaterialGroupSize = 64;
class FEvaluateSurfelMaterialCS : public FMaterialShader
{
DECLARE_SHADER_TYPE(FEvaluateSurfelMaterialCS,Material)
public:
static bool ShouldCache(EShaderPlatform Platform, const FMaterial* Material)
{
//@todo - lit materials only
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5) && DoesPlatformSupportDistanceFieldGI(Platform);
}
static void ModifyCompilationEnvironment(EShaderPlatform Platform, const FMaterial* Material, FShaderCompilerEnvironment& OutEnvironment)
{
FMaterialShader::ModifyCompilationEnvironment(Platform,OutEnvironment);
OutEnvironment.SetDefine(TEXT("EVALUATE_SURFEL_MATERIAL_GROUP_SIZE"), GEvaluateSurfelMaterialGroupSize);
OutEnvironment.SetDefine(TEXT("HAS_PRIMITIVE_UNIFORM_BUFFER"), 1);
}
FEvaluateSurfelMaterialCS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMaterialShader(Initializer)
{
SurfelBufferParameters.Bind(Initializer.ParameterMap);
SurfelStartIndex.Bind(Initializer.ParameterMap, TEXT("SurfelStartIndex"));
NumSurfelsToGenerate.Bind(Initializer.ParameterMap, TEXT("NumSurfelsToGenerate"));
Instance0InverseTransform.Bind(Initializer.ParameterMap, TEXT("Instance0InverseTransform"));
}
FEvaluateSurfelMaterialCS()
{
}
void SetParameters(
FRHICommandList& RHICmdList,
const FSceneView& View,
int32 SurfelStartIndexValue,
int32 NumSurfelsToGenerateValue,
const FMaterialRenderProxy* MaterialProxy,
FUniformBufferRHIParamRef PrimitiveUniformBuffer,
const FMatrix& Instance0Transform
)
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
FMaterialShader::SetParameters(RHICmdList, ShaderRHI, MaterialProxy, *MaterialProxy->GetMaterial(View.GetFeatureLevel()), View, true, ESceneRenderTargetsMode::SetTextures);
SetUniformBufferParameter(RHICmdList, ShaderRHI,GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(),PrimitiveUniformBuffer);
const FScene* Scene = (const FScene*)View.Family->Scene;
FUnorderedAccessViewRHIParamRef UniformMeshUAVs[1];
UniformMeshUAVs[0] = Scene->DistanceFieldSceneData.SurfelBuffers->Surfels.UAV;
RHICmdList.TransitionResources(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EComputeToCompute, UniformMeshUAVs, ARRAY_COUNT(UniformMeshUAVs));
SurfelBufferParameters.Set(RHICmdList, ShaderRHI, *Scene->DistanceFieldSceneData.SurfelBuffers, *Scene->DistanceFieldSceneData.InstancedSurfelBuffers);
SetShaderValue(RHICmdList, ShaderRHI, SurfelStartIndex, SurfelStartIndexValue);
SetShaderValue(RHICmdList, ShaderRHI, NumSurfelsToGenerate, NumSurfelsToGenerateValue);
SetShaderValue(RHICmdList, ShaderRHI, Instance0InverseTransform, Instance0Transform.Inverse());
}
void UnsetParameters(FRHICommandList& RHICmdList, FViewInfo& View)
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
SurfelBufferParameters.UnsetParameters(RHICmdList, ShaderRHI);
const FScene* Scene = (const FScene*)View.Family->Scene;
FUnorderedAccessViewRHIParamRef UniformMeshUAVs[1];
UniformMeshUAVs[0] = Scene->DistanceFieldSceneData.SurfelBuffers->Surfels.UAV;
RHICmdList.TransitionResources(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToCompute, UniformMeshUAVs, ARRAY_COUNT(UniformMeshUAVs));
}
virtual bool Serialize(FArchive& Ar) override
{
bool bShaderHasOutdatedParameters = FMaterialShader::Serialize(Ar);
Ar << SurfelBufferParameters;
Ar << SurfelStartIndex;
Ar << NumSurfelsToGenerate;
Ar << Instance0InverseTransform;
return bShaderHasOutdatedParameters;
}
private:
FSurfelBufferParameters SurfelBufferParameters;
FShaderParameter SurfelStartIndex;
FShaderParameter NumSurfelsToGenerate;
FShaderParameter Instance0InverseTransform;
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FEvaluateSurfelMaterialCS,TEXT("EvaluateSurfelMaterial"),TEXT("EvaluateSurfelMaterialCS"),SF_Compute);
void FUniformMeshConverter::GenerateSurfels(
FRHICommandListImmediate& RHICmdList,
FViewInfo& View,
const FPrimitiveSceneInfo* PrimitiveSceneInfo,
const FMaterialRenderProxy* MaterialProxy,
FUniformBufferRHIParamRef PrimitiveUniformBuffer,
const FMatrix& Instance0Transform,
int32 SurfelOffset,
int32 NumSurfels)
{
const FMaterial* Material = MaterialProxy->GetMaterial(View.GetFeatureLevel());
const FMaterialShaderMap* MaterialShaderMap = Material->GetRenderingThreadShaderMap();
FEvaluateSurfelMaterialCS* ComputeShader = MaterialShaderMap->GetShader<FEvaluateSurfelMaterialCS>();
RHICmdList.SetComputeShader(ComputeShader->GetComputeShader());
ComputeShader->SetParameters(RHICmdList, View, SurfelOffset, NumSurfels, MaterialProxy, PrimitiveUniformBuffer, Instance0Transform);
DispatchComputeShader(RHICmdList, ComputeShader, FMath::DivideAndRoundUp(NumSurfels, GEvaluateSurfelMaterialGroupSize), 1, 1);
ComputeShader->UnsetParameters(RHICmdList, View);
}